2009-12-10 18 views
34

Tôi muốn tạo một tệp giả lớn cho biết 1 ~ 2 GB trong vài giây. đây là những gì tôi đã viết bằng C#:Tạo một tệp giả lớn trong một vài giây trong C#

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

và một cách khác với báo hiệu trạng thái, giống như sau:

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(); 

nơi din là Disk Thông tin đối tượng

tốt với những hai phương pháp tiếp cận phải mất một cái gì đó giống như 2 hoặc nhiều phút để viết một tập tin lớn nhưng giả. có cách nào khác nhanh hơn để làm như vậy không?

liên quan.

+3

BinaryWriter là để viết POCO vào một tệp theo định dạng .NET có thể đọc lại, nó không phải là những gì bạn mong đợi từ tên. –

Trả lời

67

Đơn giản chỉ cần tạo ra các tập tin, tìm cách một phù hợp lớn bù đắp, và viết một byte duy nhất:

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

này sẽ mang lại một file 2GB với nội dung cơ bản không thể đoán trước, mà nên sử dụng tốt cho mục đích của bạn.

+1

+1 cho một giải pháp hấp dẫn đơn giản (giả sử nội dung giả là ok). – Abel

+0

sẽ mất một khoảng thời gian để ghi tệp giả vào ổ đĩa/flash/ram lạnh (tôi gần như quên nói rằng tôi đang sử dụng bộ nhớ có thể tháo rời). –

+6

Nội dung không thể đoán trước: tệp sẽ được điền bằng số không khi bạn viết. Nếu điều đó không được thực hiện, nó sẽ là một vấn đề an ninh. – RickNZ

0

Tôi có thể sai nhưng có thể bạn sẽ thấy rằng không thể tạo một tệp lớn nhanh như có một nút cổ chai trong quy trình viết I/O.

Tuy nhiên, trong mã của bạn phía trên Applciation.DoEvents sẽ làm chậm mọi thứ. Ngoài ra, việc sơn lại screenthis.label2.Text = sẽ làm chậm một chút.

4

Nếu bạn chỉ cần một FileStream, bạn có thể sử dụng FileStream.SetLength. Điều đó sẽ giúp bạn có một luồng dài 2 GB. Sau đó, bạn có thể viết byte cuối cùng ở vị trí tùy ý mà bạn chọn. Nhưng nội dung sẽ không được xác định.

Nếu bạn đang cố thực sự tạo tệp trên đĩa, vâng, bạn sẽ cần phải viết nội dung của nó. Và có, đĩa cứng sẽ chậm; một cái gì đó giống như tốc độ ghi 1 GB/phút không hoàn toàn vô lý. Xin lỗi - đó là vật lý!

60

Nếu bạn không quan tâm đến nội dung, sau đó do sự xa cách nhanh nhất tôi biết là thế này - đó là thực tế ngay lập tức:

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

+1 để hiển thị 'using' và làm cho câu trả lời của mdb thậm chí còn đơn giản hơn. – Abel

+9

Ngoài sự tò mò, đã thử nghiệm các phương pháp 'SetLength' và' Seek' + 'WriteByte'. Với * Tìm kiếm * mất 15 giây cho 512MB, chỉ với * SetLength * mất khoảng 1 giây. Trong cả hai trường hợp, thậm chí sau nhiều lần kiểm tra, các tệp được điền bằng NULL (trái ngược với dữ liệu tùy ý). Không chắc chắn nếu đó là một đĩa sạch hoặc một số tối ưu không đệm tạo dưới mui xe. – Abel

+0

Điểm tốt - rất thú vị. Tôi có thể xác nhận tương tự trên tôi; Tôi muốn nguy hiểm đoán rằng nó không có khả năng là một đĩa sạch trong trường hợp của tôi (lộn xộn và đầy đủ đĩa cứng!) –

2

Tại sao bạn không sử dụng lớp BackgroundWorker để đạt được điều này, khi bạn có thể chuyển bất kỳ thứ gì vào phương thức ReportProgress để cho biết báo cáo trạng thái. Xem ví dụ dưới đây:

 
     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; 
    } 
} 
} 

Đây là một dự thảo thô ... Hope this helps, Trân trọng, Tom.

Các vấn đề liên quan