C # добавление байтов в начало файла? - PullRequest
3 голосов
/ 03 сентября 2011

Какой самый быстрый и эффективный способ добавить байты в начале файла? По сути, я хочу открыть файл, а затем добавить к нему количество байтов. Я думал об использовании цикла, но, учитывая, что все байты для добавления одинаковы, я не думаю, что это будет необходимо.

Ответы [ 4 ]

9 голосов
/ 03 сентября 2011

Один подход, который не атомарный по отношению к файлу (то есть, если программа умирает посередине, данные могут остаться в несогласованном состоянии):

  1. Открыть файл.
  2. Начиная с end , переместите байты назад на дополнительную разницу в размере. Это должно быть сделано в блоках (например, ReadBytes), а не в байтах за раз - см. лучший способ копирования между потоками для примера.
  3. Введите новые данные в начале файла.

Однако этот подход может также привести к путанице в схеме упреждающего чтения файловой системы и требует поиска / произвольного доступа к файлу. Из-за этих проблем я могу честно порекомендовать его только в том случае, если пространство на устройстве является абсолютной премией.

Другой подход, атомарный по отношению к файлу (если программа умирает на каком-либо этапе, данные не теряются и процесс может быть восстановлен):

  1. Открыть старый файл.
  2. Создать новый файл.
  3. Заполните данные в новом файле.
  4. Переместить данные из старого файла в новый файл (еще раз ReadBytes) - в этом случае ранее связанный SO вопрос должен "просто работать как есть".
  5. Удалить старый файл и переименовать новый файл в старый файл.

Недостатком является то, что для этого требуется временный файл.

Удачного кодирования.

4 голосов
/ 03 сентября 2011

Если вам действительно нужно сделать предисловие, наиболее «безопасный» способ - это записать в новый файл ваши байты, записать в этот новый файл старый файл и в конце поменять местами файлы (используя, например, File.Replace ииспользуя null в качестве destinationBackupFileName.).Имейте в виду, что вам нужно достаточно места для копирования старого файла!

3 голосов
/ 03 сентября 2011

Это самый лаконичный способ, который я лично мог придумать, но он не избегает циклов, как вы хотели:

int numberOfBytes = 100;
byte newByte = 0x1;

using ( var newFile = new FileStream( @"C:\newfile.dat", FileMode.CreateNew, FileAccess.Write ) )
{
    for ( var i = 0; i < numberOfBytes; i++ )
    {
        newFile.WriteByte( newByte );
    }
    using ( var oldFile = new FileStream( @"C:\oldfile.dat", FileMode.Open, FileAccess.Read ) )
    {
        oldFile.CopyTo(newFile);
    }
}

// Rename and delete files, or whatever you want to do

Можно также использовать некоторую обработку ошибок, но вы поняли идею.

0 голосов
/ 03 сентября 2011

Самый простой способ сделать это - создать байтовый массив, добавить байты «prepend», а затем преобразовать файл, который вы хотите использовать, в другой байтовый массив и объединить их вместе!

...