Подтвердить что ты не робот

Улучшить скорость разбиения файла

Я использую этот код для извлечения фрагмента из файла

// info is FileInfo object pointing to file
var percentSplit = info.Length * 50 / 100; // extract 50% of file
var bytes = new byte[percentSplit];
var fileStream = File.OpenRead(fileName);
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Dispose();
File.WriteAllBytes(splitName, bytes);

Есть ли способ ускорить этот процесс?

В настоящее время для файла объемом 530 МБ требуется около 4 - 5 секунд. Может ли это время быть улучшено?

4b9b3361

Ответ 1

Есть несколько случаев, когда вы задаете вопрос, но ни один из них не является релевантным для языка.

Ниже следует что-то относиться к

  • Что такое файловая система исходного/целевого файла?
  • Вы хотите сохранить исходный исходный файл?
  • Они лежат на одном диске?

В С# у вас почти нет метода, который может быть быстрее, чем File.Copy, который внутренне вызывает CopyFile of WINAPI. Однако из-за того, что процент составляет пятьдесят, следующий код может быть не быстрее. Он копирует весь файл, а затем устанавливает длину целевого файла

var info=new FileInfo(fileName);
var percentSplit=info.Length*50/100; // extract 50% of file

File.Copy(info.FullName, splitName);
using(var outStream=File.OpenWrite(splitName))
    outStream.SetLength(percentSplit);

Далее, если

  • вы не сохраняете исходный источник после разбиения файла.
  • целевой диск совпадает с исходным кодом
  • вы не используете файловую систему crypto/compression enabled

тогда самое лучшее, что вы можете сделать, не копировать файлы вообще. Например, если ваш исходный файл находится в файловой системе FAT или FAT32, то вы можете сделать это

  • создать новую запись dir (записи) для недавно разделенных частей файла
  • пусть точка (записи) записи (записей) в кластер целевой части (-ов)
  • установить правильный размер файла для каждой записи
  • проверьте наличие перекрестных ссылок и избегайте этого.

Если ваша файловая система была NTFS, вам может потребоваться потратить много времени на изучение спецификации.

Удачи!

Ответ 2

var percentSplit = (int)(info.Length * 50 / 100); // extract 50% of file
var buffer = new byte[8192];
using (Stream input = File.OpenRead(info.FullName))
using (Stream output = File.OpenWrite(splitName))
{
    int bytesRead = 1;
    while (percentSplit > 0 && bytesRead > 0)
    {
        bytesRead = input.Read(buffer, 0, Math.Min(percentSplit, buffer.Length));
        output.Write(buffer, 0, bytesRead);
        percentSplit -= bytesRead;
    }
    output.Flush();
}

Флеш может не понадобиться, но это не повредит, это было довольно интересно, изменив цикл на пока-то, а не на время сильно поразив производительность. Я полагаю, что ИЛ не так быстро. Мой компьютер запускал исходный код через 4-6 секунд, вложенный код, казалось, работал примерно через 1 секунду.

Ответ 3

Я получаю лучшие результаты при чтении/записи кусками в несколько мегабайт. Производительность изменяется также в зависимости от размера куска.

FileInfo info = new FileInfo(@"C:\source.bin");
FileStream f = File.OpenRead(info.FullName);
BinaryReader br = new BinaryReader(f);

FileStream t = File.OpenWrite(@"C:\split.bin");
BinaryWriter bw = new BinaryWriter(t);

long count = 0;
long split = info.Length * 50 / 100;
long chunk = 8000000;

DateTime start = DateTime.Now;

while (count < split)
{
    if (count + chunk > split)
    {
        chunk = split - count;
    }

    bw.Write(br.ReadBytes((int)chunk));
    count += chunk;
}

Console.WriteLine(DateTime.Now - start);

Ответ 4

Я думаю, что самый быстрый способ обойти эту проблему - через двоичный буферный ввод файла.

Я не очень хорошо знаком с С#, но вы можете изучить некоторые методы буферизации для перехода к определенной части файла и делать буферизованный ввод из этой части.

Вы также можете прибегнуть к использованию С++ с Windows API для собственных методов буферизации или найти библиотеки, которые имеют быстрые методы буферизации.

Я не могу предложить много другого, надеюсь, это поможет.