2009-12-10 4 views
34

몇 초 만에 1 ~ 2GB의 거대한 더미 파일을 만들고 싶습니다. 여기 내가 C#으로 작성한 것입니다 :C#에서 초당 중요한 거대한 더미 파일 만들기

long FSS = din.TotalFreeSpace; 
long segments = FSS/10000; 
long last_seg = FSS % 10000; 
BinaryWriter br = new BinaryWriter(fs); 

for (long i = 0; i < segments; i++) 
{ 
    br.Write(new byte[10000]); 

    this.label2.Text = "segments write :" + i.ToString() + "\r\n" + "segments remain :" + ((segments-i)+1).ToString(); 
    Application.DoEvents(); 
} 
br.Write(new byte[last_seg]); 
this.label2.Text += "\r\nDone!"; 
br.Close(); 
는 소음이 디스크 정보입니다

이 잘

객체 :

file.writeallbytes("filename",new byte[a huge number]); 

과 상태를 나타내는 또 다른 방법으로, 다음과 같았다 두 가지 접근법은 크지 만 더미 파일을 작성하는 데 2 ​​분 이상 걸립니다. 그렇게하기위한 다른 빠른 방법이 있습니까?

안부.

+3

BinaryWriter는 POCO를 .NET에서 다시 읽을 수있는 형식으로 파일에 쓰는 데 사용됩니다. 이름에서 예상하는 형식이 아닙니다. –

답변

67

는 단순히 파일을 작성 오프셋 적절히 큰 추구, 쓰기 1 바이트 :

FileStream fs = new FileStream(@"c:\tmp\huge_dummy_file", FileMode.CreateNew); 
fs.Seek(2048L * 1024 * 1024, SeekOrigin.Begin); 
fs.WriteByte(0); 
fs.Close(); 

이것은 당신의 목적을 위해 잘해야한다 기본적으로 예측할 수없는 내용과 2GB의 파일을 얻을 것입니다.

+1

+1은 흥미 진진하게 간단한 해결책입니다 (더미 내용은 괜찮다고 가정). – Abel

+0

더미 파일을 cool/flash/ram 디스크에 쓰려면 동일한 양의 시간이 걸릴 것입니다 (나는 이동식 저장소를 사용하고 있다고 거의 잊지 않습니다). –

+6

내용을 예측할 수 없습니다. 쓰기를 수행하면 파일이 0으로 채워집니다. 그렇게하지 않으면 보안 문제가 될 것입니다. – RickNZ

0

내가 틀릴 수도 있지만 I/O 작성 과정에서 병목 현상이 발생할 수 있으므로 큰 파일을 만드는 것은 불가능합니다.

위의 코드에서 Applciation.DoEvents는 작업 속도를 저하시킵니다. screenthis.label2.Text =도 다시 칠하면 약간 느려집니다.

4

FileStream 만 있으면 FileStream.SetLength을 사용할 수 있습니다. 그러면 2GB의 스트림을 얻을 수 있습니다. 그런 다음 원하는 임의의 위치에 최종 바이트를 쓸 수 있습니다. 그러나 내용은 정의되지 않을 것입니다.

실제로 디스크에 파일을 만들려는 경우 실제로 해당 내용을 작성해야합니다. 그리고 예, 하드 디스크가 느려질 것입니다; 1GB/분의 쓰기 속도와 같은 것은 완전히 우스꽝스럽지 않습니다. 미안해 - 물리학이야!

60

당신은 내가 아는 지금까지 가장 빠른 방법으로 다음 내용에 대해 상관하지 않는 경우이 - 그것은 실질적으로 인스턴트입니다 :

private void CreateDummyFile(string fileName, long length) 
{ 
    using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) 
    { 
     fileStream.SetLength(length); 
    } 
} 
+0

+1의 파일을 생성합니다. – Abel

+9

호기심에서 벗어나 테스트 된'SetLength'와'Seek' +'WriteByte' 접근법. * Seek *를 사용하면 512MB의 경우 15 초가 걸리며 * SetLength *는 약 1 초가 걸립니다. 두 경우 모두 많은 테스트를 거친 후에도 파일은 NULL로 채워졌습니다 (임의의 데이터와 반대). 깨끗한 디스크인지 최적화 된 제로 패딩 된 제작인지 확실하지 않습니다. – Abel

+0

좋은 장소 - 매우 흥미 롭습니다. 나는 내 것을 똑같이 확인할 수있다. 내 경우에는 (지저분하고 전체 하드 디스크!) 깨끗한 디스크가 될 것 같지 않은 것 같아요 –

2

왜 당신이 이것을 달성하기 위해 BackgroundWorker 클래스를 사용하지 않은, ReportProgress 메서드에 아무 것도 전달하지 않아 상태 보고서를 나타낼 수 있습니다. 이 도움이

 
     private BackgroundWorker bgWorker; 
     public Form1() 
     { 
      InitializeComponent(); 
      bgWorker = new BackgroundWorker(); 
      bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
      bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
      bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
      bgWorker.RunWorkerAsync(); 
     } 

     void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      this.label2.Text = "Done"; 
     } 

     void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      MyStatus myProgressStatus = (MyStatus)e.UserState; 
      this.label2.Text = string.Format("segments write : {0}" + Environment.Newline + "Segments Remain: {1}", myProgressStatus.iWritten, myProgressStatus.iRemaining); 
     } 

     void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      long FSS = din.TotalFreeSpace; 
       long segments = FSS/10000; 
       long last_seg = FSS % 10000; 
       BinaryWriter br = new BinaryWriter(fs); 

       for (long i = 0; i < segments; i++) 
       { 
        br.Write(new byte[10000]); 
bgWorker.ReportProgress(i.ToString(), new MyStatus(i, ((segments-i) + 1))); 

       } 
       br.Write(new byte[last_seg]); 
       br.Close(); 
     } 

public class MyStatus{ 
    public int iWritten; 
    public int iRemaining; 
    public MyStatus(int iWrit, int iRem){ 
    this.iWritten = iWrit; 
    this.iRemaining = iRem; 
    } 
} 
} 

이 초안은 ... 희망, 안부, 톰 : 아래의 예를 참조하십시오.