创建大量小文件的最佳方式

本文关键字:最佳 方式 文件 小文 创建 | 更新日期: 2023-09-27 17:55:04

我想尽快创建很多(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);
    }
}

我可以加速吗?

roomaroo对,我需要使用Parallel,但我将它与我的函数结合起来,这有一个更好的结果。代码:

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

创建大量小文件的最佳方式

按照ChrisBint的建议,使用并行循环。

我创建了三个方法来编写文件(下面的代码)。一个使用上面的代码,一个使用File.WriteAllBytes(…)——它们都使用传统的for循环。

第三个实现使用了并行的for循环。

下面是创建1000个文件的次数:

文件流:2658 ms

文件。WriteAllBytes: 2555ms

平行。: 617 ms

所以并行循环比最慢的实现快四倍。显然,这将在不同的硬件上有所不同,并且您的结果将在很大程度上取决于您的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);
        }
    }
}