Исключение IOException чтение большого файла из UNC-пути в массив байтов с использованием .NET
-
23-08-2019 - |
Вопрос
Я использую следующий код, чтобы попытаться прочитать большой файл (280 МБ) в массив байтов из UNC-пути
public void ReadWholeArray(string fileName, byte[] data)
{
int offset = 0;
int remaining = data.Length;
log.Debug("ReadWholeArray");
FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}
Это приводит к следующей ошибке.
System.IO.IOException: Insufficient system resources exist to complete the requested
Если я запускаю это, используя локальный путь, это работает нормально, в моем тестовом примере путь UNC фактически указывает на локальное поле.
Есть какие - нибудь мысли о том , что здесь происходит ?
Решение
Я подозреваю, что что-то ниже пытается прочитать в другой буфер, и чтение всех 280 МБ за один раз завершается неудачей.В сетевом случае может потребоваться больше буферов, чем в локальном.
Я бы прочитал около 64 тысяч за раз, вместо того чтобы пытаться прочитать все сразу.Этого достаточно, чтобы избежать слишком больших накладных расходов из-за фрагментации, но при этом не потребуются огромные буферы.
Лично я склонен просто дочитывать поток до конца, а не предполагать, что размер файла останется постоянным.Видишь этот вопрос для получения дополнительной информации.
Другие советы
Кроме того, в написанном виде код должен содержать FileStream
в using
блок.Неспособность распоряжаться ресурсами является весьма возможной причиной получения "Недостаточных системных ресурсов".:
public void ReadWholeArray(string fileName, byte[] data)
{
int offset = 0;
int remaining = data.Length;
log.Debug("ReadWholeArray");
using(FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}
}
Похоже, что массив не был создан с достаточным размером.Какой размер массива выделяется до его передачи?Или вы предполагали, что функция чтения будет перераспределять массив данных по мере необходимости?Этого не произойдет.Редактировать:Э-э, может быть, и нет, я просто заметил исключение, которое у вас есть.Сейчас не уверен.