2013-01-22 45 views
1

我想創造出很多(100萬)的小文件儘快,這就是我現在做的事情:創建大量小文件的最佳方法?

for(long i = 0; i < veryVeryLong; i++){ 
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) { 
     byte[] bytes = GetFileContent(i); // no matter 
     fs.Write(bytes, 0, bytes.Length); 
    } 
} 

能否加快?

UPDATE

roomaroo吧,我需要使用平行的,但我有我的功能相結合,並這有一個更好的結果。代碼:

Parallel.For(0, veryVeryLogn, (i) => { 
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) { 
     byte[] bytes = GetFileContent(i); // no matter 
     fs.Write(bytes, 0, bytes.Length); 
    } 
}); 
+0

你可以在東西平行。 – ChrisBint

+0

不知道是否可以幫助你..但有一個命令行實用程序來創建文件..「fsutil文件創建新」 – 2GDev

+1

因爲你使用C#,你可能想看看這個問題:http://stackoverflow.com/questions/8979686 /最快的方式來創建文件在C - 銳?rq = 1 –

回答

3

正如ChrisBint建議的那樣,使用並行循環。

我創建了三種寫文件的方法(代碼如下)。一個使用上面的代碼,一個使用File.WriteAllBytes(...) - 這兩個都使用傳統的for循環。

第三個實現使用了並行for循環。

以下是創建1000個文件的時間:

的FileStream:2658ms

File.WriteAllBytes:2555ms

的Parallel.For:617ms

所以並行循環比最慢的實施快四倍。顯然,這將在不同的硬件上有所不同,並且您的結果將非常依賴於您的CPU和磁盤。

下面的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Diagnostics; 
using System.Threading.Tasks; 

namespace FileCreator 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string folder = @"d:\temp"; 

      Clean(folder); 
      CreateWithParallelFileWriteBytes(folder); 

      Clean(folder); 
      CreateWithFileStream(folder); 

      Clean(folder); 
      CreateWithFileWriteBytes(folder); 
     } 

     private static void Clean(string folder) 
     { 
      if (Directory.Exists(folder)) 
      { 
       Directory.Delete(folder, true); 
      } 

      Directory.CreateDirectory(folder); 
     } 

     private static byte[] GetFileContent(int i) 
     { 
      Random r = new Random(i); 
      byte[] buffer = new byte[1024]; 
      r.NextBytes(buffer); 
      return buffer; 
     } 

     private static void CreateWithFileStream(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      for (int i = 0; i < 1000; i++) 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 

       using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) 
       { 
        byte[] bytes = GetFileContent(i); 
        fs.Write(bytes, 0, bytes.Length); 
       } 
      } 

      Console.WriteLine("Time for CreateWithFileStream: {0}ms", sw.ElapsedMilliseconds); 
     } 

     private static void CreateWithFileWriteBytes(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      for (int i = 0; i < 1000; i++) 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 
       File.WriteAllBytes(path, GetFileContent(i)); 
      } 

      Console.WriteLine("Time for CreateWithFileWriteBytes: {0}ms", sw.ElapsedMilliseconds); 
     } 

     private static void CreateWithParallelFileWriteBytes(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      Parallel.For(0, 1000, (i) => 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 
       File.WriteAllBytes(path, GetFileContent(i)); 
      }); 

      Console.WriteLine("Time for CreateWithParallelFileWriteBytes: {0}ms", sw.ElapsedMilliseconds); 
     } 
    } 
} 
+0

如果您先運行並行版本,那麼時間有沒有變化?如果文件已經在磁盤上,創建文件有時會更快。 –

+0

似乎並不影響時代。平行版本仍然約600ms。 – roomaroo

+0

我已更新到代碼,因此它會刪除每個測試之間的輸出文件夾,以使事情更公平。時間大致相同(2715ms/2608ms/602ms)。 – roomaroo

相關問題