С# загрузка бинарных файлов

Пожалуйста, покажите мне лучшие/быстрые методы для:

1) Загрузка очень маленьких бинарных файлов в память. Например иконки;

2) Загрузка/чтение очень больших бинарных файлов размером 512Mb+.

3) Ваш обычный выбор, когда вы не хотите думать о размере/скорости, а должны сделать только одно: прочитать все байты в память?

Спасибо!!!

P.S. Извините за, может быть, тривиальный вопрос. Пожалуйста, не закрывайте его ;)

P.S.2. Зеркало аналогового вопроса для Java;


person Edward83    schedule 22.11.2010    source источник
comment
Вам может быть интересна следующая статья: codeproject.com/KB/files/fastbinaryfileinput .aspx   -  person Cody Gray    schedule 22.11.2010


Ответы (4)


1: Для очень маленьких файлов File.ReadAllBytes подойдет.

2: Для очень больших файлов и использования .net 4.0 вы можете использовать файлы MemoryMapped.

3: Если не используется .net 4.0, чем .net, чтение фрагментов данных будет хорошим выбором.

person TalentTuner    schedule 22.11.2010
comment
Все ответы имеют причины быть полезными. Но для больших файлов я предпочитаю MemoryMapped Files — мои старые добрые друзья из нативного Windows API;) - person Edward83; 27.11.2010

1) Я бы использовал файл ресурсов, а не хранил его в виде множества отдельных файлов.

2) вы, вероятно, хотите передавать данные, а не читать их все сразу, и в этом случае вы можете использовать FileStream.

3): используйте ReadAllBytes:

byte[] bytes = File.ReadAllBytes(path);
person Mark Byers    schedule 22.11.2010

1: для маленьких File.ReadAllBytes

2: Для большого потока (FileStream) или BinaryReader в потоке — цель состоит в том, чтобы устранить необходимость выделения массивного буфера путем изменения кода для последовательного чтения небольших фрагментов.

3: Вернитесь назад и найдите ожидаемый размер; по умолчанию для наихудшего случая (# 2)

Также обратите внимание, что я бы попытался минимизировать siE в первую очередь, возможно, за счет выбора формата данных или сжатия.

person Marc Gravell    schedule 22.11.2010

Этот пример хорош для обоих — для больших файлов вам нужно буферизованное чтение.

 public static byte[] ReadFile(string filePath)
 {
  byte[] buffer;
  FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  try
    {
     int length = (int)fileStream.Length;  // get file length
     buffer = new byte[1024];            // create buffer
     int count;                            // actual number of bytes read
     int sum = 0;                          // total number of bytes read

     // read until Read method returns 0 (end of the stream has been reached)
     while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
      sum += count;  // sum is a buffer offset for next reading
     }
     finally
     {
      fileStream.Close();
     }
      return buffer;
   }
person dexter    schedule 22.11.2010
comment
Это не лучше (хорошо для обоих), чем File.ReadAllBytes; зачем изобретать работу? - person Marc Gravell; 22.11.2010
comment
(основная проблема здесь в необходимости выделять огромный буфер для больших файлов) - person Marc Gravell; 22.11.2010
comment
Зачем вам огромный буфер, размер буфера 1024 значительно улучшил бы скорость чтения. - person dexter; 22.11.2010
comment
@Max Malygin: Потому что в своем коде вы создаете буфер того же размера, что и файл — в примере 2 вы получите буфер длиной 536 870 912 байт, а не 1024 — вы просто говорите «Прочитать все». в этот огромный буфер, который я только что создал, вместо того, чтобы сказать «ОК», формат этого двоичного файла следующий: первые 2 байта говорят мне, какой файл у меня есть; затем следующие 50 байтов являются заголовком со следующими данными: 2 байта: количество элементов; 10 байт: длина элемента; и т. д., где вы можете разделить чтение только на те байты, которые вас интересуют в данный момент. - person Zhaph - Ben Duguid; 22.11.2010
comment
Да, это правильно, извините, нужно быть намного меньше ... моя ошибка. Исправлено. - person dexter; 22.11.2010
comment
@Max - это все еще не работает, вы получите исключение: смещение и длина вышли за пределы массива .... Вы просите метод Read попытаться поместить весь файл в 1024 байтовый массив (длина-сумма). Если бы вы изменили это, чтобы просто прочитать 1024 байта, у вас все равно возникла бы проблема во второй раз, поскольку вы просите Read начать заполнение массива байтов после конца массива (с позиции 1024). Ваш вызов read, вероятно, должен выглядеть так: Read(buffer, 0, 1024), а затем явно указать, что вам нужно иметь дело с содержимым буфера. bit.ly/hxVLbH - person Zhaph - Ben Duguid; 23.11.2010
comment
Декстер, ты, наверное, думаешь, что смещение и длина в методе Read относятся к файлу, а они к буферу. - person greenoldman; 23.09.2011