Я получаю свой набор изображений из WebAPI в виде списка объектов ImageData, каждый из которых содержит байтовый массив.
public class ImageData
{
public byte[] data;
}
Когда у меня много изображений небольшого размера, я могу получить ответ API и десериализовать его с помощью JObject без проблем. Ниже работает отлично.
using (var sr = new StreamReader(stream))
using (var jr = new JsonTextReader(sr))
{
while (jr.Read())
{
if (jr.TokenType == JsonToken.StartObject)
{
imageData = JObject.Load(jr).ToObject<ImageData>();
}
}
}
Однако иногда у меня есть один очень большой файл изображения (более 200 МБ). В этом случае обычный метод десериализации не работает. Я продолжаю получать исключения OutOfMemory.
Я пытался прочитать ответ в буферах и получить байтовый массив, но конечный размер всех прочитанных байтов всегда больше, чем фактический размер изображения. Если исходный размер изображения составляет около 220 МБ, то я получаю около 295 МБ, думаю, из-за кодирования. Таким образом, изображение никогда не может быть правильно написано. Ниже показано, как я делаю буферизованное чтение.
byte[] buffer = new byte[1024];
List<byte[]> imageBytes = new List<byte[]>();
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
imageBytes.Add(buffer);
}
var output = new byte[imageBytes.Sum(arr => arr.Length)];
int writeIdx = 0;
foreach (var byteArr in imageBytes)
{
byteArr.CopyTo(output, writeIdx);
writeIdx += byteArr.Length;
}
imageData = new ImageData() { data = output };
Что мне здесь не хватает? Как я могу выполнить sh получение данных изображения из этой огромной полезной нагрузки без исключений памяти или дополнительных байтов?
---- Обновление ---
Я пробовал с ниже, но все еще больше число байтов, чем в оригинале.
while (true)
{
read = await stream.ReadAsync(buffer, 0, 1024);
++count;
if (read <= 0)
bytesRead += read;
ms.Write(buffer, 0, read);
}
imageData = new ImageData() { data = ms.ToArray() };
При использовании FileStream размер temp.dcm снова составляет около 290 МБ, а исходного изображения - около 210 МБ:
string file = @"C:\Test\\temp.dcm";
using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write,
FileShare.None, 4096, useAsync: true))
{
await response.Content.CopyToAsync(fs);
}