Я пытаюсь сериализовать большие данные.Я получаю ошибку OutOfMemoryException при сериализации данных.Я сделал некоторые исследования.Я нашел некоторую информацию, что сказано, что есть ошибка о MemoryStream.Потому что поток памяти поддерживает размер данных 2 ГБ.Он имеет емкость как целое число.Я обнаружил, что вместо потока памяти можно использовать другой класс.Это называется MemoryTributary.Я попробовал этот класс.Но это дало мне действительно плохую производительность.Могу ли я найти основу или другую вещь, как поток памяти для больших данных?
Я хотел бы поделиться тем, что я сделал в ближайшее время:
- Получить данные из SQLServer
- Преобразовать данные в структуру
- СериализацияДанные
- Сжатие данных с использованием алгоритма LZ4
- Загрузка данных в Azure
- Получение данных из Azure
- Распаковка данныхС помощью алгоритма LZ4
- Десериализация данных
- Использование данных для работы
У меня есть несколько кодов, как показано ниже:
public static Stream ConvertObjectToStream<T>(T obj)
{
if (obj == null) return null;
var boisSerializer = new BoisSerializer();
try
{
var mem = new MemoryStream();
boisSerializer.Serialize(obj, mem);
return new MemoryStream(mem.ToArray());
}
catch (OutOfMemoryException)
{
var mem = new MemoryTributary();
boisSerializer.Serialize(obj, mem);
return new MemoryTributary(mem.ToArray());
}
}
public static Stream ConvertObjectToStream(object obj)
{
if (obj == null) return null;
var boisSerializer = new BoisSerializer();
try
{
var mem = new MemoryStream();
boisSerializer.Serialize(obj, obj.GetType(), mem);
return new MemoryStream(mem.ToArray());
}
catch (OutOfMemoryException)
{
var mem = new MemoryTributary();
boisSerializer.Serialize(obj, mem);
return new MemoryTributary(mem.ToArray());
}
}
public static T ConvertStreamToObject<T>(Stream stream)
{
stream.Position = 0;
var boisSerializer = new BoisSerializer();
var o = boisSerializer.Deserialize<T>(stream);
return o;
}
public static object ConvertStreamToObject(Stream stream, Type type)
{
stream.Position = 0;
var boisSerializer = new BoisSerializer();
object o = boisSerializer.Deserialize(stream, type);
return o;
}
public static Stream CompressStream(this Stream stream, LZ4Level lz4Level = LZ4Level.L00_FAST)
{
stream.Position = 0;
var ms = new MemoryStream();
var settings = new LZ4EncoderSettings { CompressionLevel = lz4Level };
LZ4EncoderStream target = LZ4Stream.Encode(ms, settings);
stream.CopyTo(target);
target.Dispose();
ms.Dispose();
return new MemoryStream(ms.ToArray());
}
public static Stream DecompressStream(this Stream stream)
{
var ms = new MemoryStream();
stream.Position = 0;
LZ4DecoderStream source = LZ4Stream.Decode(stream);
source.CopyTo(ms);
source.Dispose();
ms.Dispose();
return new MemoryStream(ms.ToArray());
}
public async Task UploadValueToContainer<T>(string containerName, string blobName, T obj)
{
Stream stream = Core.Tools.Helpers.ConvertObjectToStream(obj).CompressStream();
CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
if (!container.Exists()) throw new Exception($"{containerName} Container has not been found.");
CloudBlockBlob blobData = container.GetBlockBlobReference(blobName);
await blobData.UploadFromStreamAsync(stream);
}
public async Task<T> DownloadValueFromContainer<T>(string containerName, string blobName) where T : new()
{
CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
if (!container.Exists()) throw new Exception($"{containerName} Container has not been found.");
CloudBlockBlob blobData = container.GetBlockBlobReference(blobName);
if (!blobData.Exists())
{
return new T();
}
try
{
var ms = new MemoryStream();
await blobData.DownloadToStreamAsync(ms);
return Core.Tools.Helpers.ConvertStreamToObject<T>(ms.DecompressStream());
}
catch (OutOfMemoryException)
{
var ms = new MemoryTributary();
await blobData.DownloadToStreamAsync(ms);
return Core.Tools.Helpers.ConvertStreamToObject<T>(ms.DecompressStream());
}
}