Лучший способ создать много маленьких файлов?

Я хочу как можно быстрее создать много (1 миллион) маленьких файлов, вот что я делаю сейчас:

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

1 ответ

Решение

Как предложил ChrisBint, используйте параллельный цикл.

Я создал три метода для записи файлов (код ниже). Один использует ваш код выше, другой использует File.WriteAllBytes(...) - оба они используют традиционный цикл for.

Третья реализация использовала параллель для цикла.

Вот время, чтобы создать 1000 файлов:

FileStream: 2658мс

File.WriteAllBytes: 2555мс

Parallel.For: 617мс

Таким образом, параллельный цикл в четыре раза быстрее, чем самая медленная реализация. Очевидно, что это будет отличаться на разных аппаратных средствах, и ваши результаты будут очень сильно зависеть от вашего процессора и диска.

Вот код:

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);
        }
    }
}
Другие вопросы по тегам