Лучший способ считать большой файл в массив байтов в C#?

У меня есть веб-сервер, который считает большие двоичные файлы (несколько мегабайтов) в массивы байтов. Сервер мог читать несколько файлов одновременно (различные запросы страницы), таким образом, я ищу наиболее оптимизированный путь к тому, чтобы сделать это, не облагая налогом ЦП слишком много. Код ниже достаточно хорошего?

public byte[] FileToByteArray(string fileName)
{
    byte[] buff = null;
    FileStream fs = new FileStream(fileName, 
                                   FileMode.Open, 
                                   FileAccess.Read);
    BinaryReader br = new BinaryReader(fs);
    long numBytes = new FileInfo(fileName).Length;
    buff = br.ReadBytes((int) numBytes);
    return buff;
}
377
задан Peter Mortensen 26 June 2015 в 09:08
поделиться

7 ответов

[

]Просто замените все это на:[

] [
return File.ReadAllBytes(fileName);
] [

]Однако, если вас беспокоит потребление памяти, вы должны []а не [] считывать весь файл в память сразу. Вы должны делать это в кусках. [

]
754
ответ дан 22 November 2019 в 23:57
поделиться
[

] Я бы подумал:[

] [
byte[] file = System.IO.File.ReadAllBytes(fileName);
]
32
ответ дан 22 November 2019 в 23:57
поделиться
[

]Ваш код может быть учтен (вместо File.ReadAllBytes):[

] [
public byte[] ReadAllBytes(string fileName)
{
    byte[] buffer = null;
    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        buffer = new byte[fs.Length];
        fs.Read(buffer, 0, (int)fs.Length);
    }
    return buffer;
} 
] [

]Обратите внимание на ограничение размера файла Integer.MaxValue - ограничение размера файла, установленное методом чтения. Другими словами, вы можете прочитать только 2 Гб фрагмента одновременно.[

] [

]Также обратите внимание, что последним аргументом в пользу FileStream является размер буфера.[

] [

]Я также рекомендую прочитать о []FileStream[] и []BufferedStream[].[

] [

]Как всегда простой пример программы для профилирования, которая работает быстрее всего, будет наиболее полезен.[

] [

]Также ваше основное аппаратное обеспечение окажет большое влияние на производительность. Вы используете серверные жесткие диски с большим кэшем и RAID-карту со встроенным кэшем памяти? Или вы используете стандартный диск, подключенный к порту IDE?[

].
25
ответ дан 22 November 2019 в 23:57
поделиться
[

]Используйте класс BufferedStream на C# для улучшения производительности. Буфер - это блок байт в памяти, используемый для кэширования данных, что позволяет сократить количество обращений к операционной системе. Буферы улучшают производительность чтения и записи.[

] [

]Смотрите следующий пример кода и дополнительное пояснение: []http://msdn.microsoft.com/en-us/library/system.io.bufferedstream.aspx[][

]
0
ответ дан 22 November 2019 в 23:57
поделиться

Я мог бы утверждать, что ответ здесь Вообще это «не». Если вы абсолютно не нужны все данные сразу, рассмотрим использование по потоку -Based API (или некоторый вариант читателя / итератора). То есть особенно , важно, когда у вас есть несколько параллельных операций (как предложено вопрос), чтобы минимизировать нагрузку на систему и максимизировать пропускную способность.

Например, если вы передаете данные звонящему:

Stream dest = ...
using(Stream source = File.OpenRead(path)) {
    byte[] buffer = new byte[2048];
    int bytesRead;
    while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
        dest.Write(buffer, 0, bytesRead);
    }
}
66
ответ дан 22 November 2019 в 23:57
поделиться

Ошибка - это то, что неверно, неверно неправильно, никто не об этом, она должна быть исправлена.

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

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

Тем не менее, такие вещи, как «SQL-исполнение, занимают слишком длинное», может быть предупреждение, в то время как «Doblocks SQL выполнение SQL» - это ошибка, так что, возможно, есть некоторые случаи в конце концов.

-121--1805770-

В зависимости от частоты операций размером файлов, а также количество файлов, на которых вы смотрите, есть другие вопросы производительности, которые необходимо учитывать. Одна вещь, которую нужно помнить, состоит в том, что каждый из ваших массивов байтов будет выпущен во власти сборщика мусора. Если вы не кэшируете любой из этих данных, вы можете в конечном итоге создавать много мусора и потерять большую часть своей производительности на % времени в GC . Если кусочки превышают 85К, вы будете выделяться с большой кучей объекта (LOH), который потребует коллекции всех поколений, чтобы освободить (это очень дорого, а на сервере остановится все выполнение, пока он продолжат ). Кроме того, если у вас есть тонна объектов в LOH, вы можете в конечном итоге с фрагментацией LOH (LOH никогда не уплотняется), что приводит к плохой производительности и вне исключения памяти. Вы можете перерабатывать процесс, как только вы попадаете в определенный момент, но я не знаю, является ли это лучшая практика.

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

9
ответ дан 22 November 2019 в 23:57
поделиться

Я бы порекомендовал попробовать метод .transferfile () , затем A RACK.FLUSH () и Repeate.end () Для обслуживания ваших больших файлов.

-4
ответ дан 22 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: