我想尽快创建很多(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);
}
}
我可以加快速度吗?
更新
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 :(得分: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);
}
}
}