У меня есть код для загрузки произвольных объектов на AWS S3:
| Код |
| public static async Task UploadCompressedObjectToS3(IAmazonS3 s3Client, string bucketName, string objectKey, JsonSerializer serializer, object value,
IReadOnlyCollection<KeyValuePair<string, string>> metadata = null, CancellationToken ct = default )
{
using (var m = new MemoryStream())
using (var tranUtility = new TransferUtility(s3Client))
{
using (var b = new BrotliStream(m, CompressionLevel.Optimal, true))
using (var w = new StreamWriter(b, Encoding.UTF8, 16384))
{
serializer.Serialize(w, value);
await w.FlushAsync();
}
m.Seek(0, SeekOrigin.Begin);
var r = new TransferUtilityUploadRequest
{
BucketName = bucketName,
AutoCloseStream = true,
AutoResetStreamPosition = true,
InputStream = m,
Key = objectKey,
};
r.AddHeaders(metadata);
r.AddCompressionHeader();
await tranUtility.UploadAsync(r, ct);
}
}
|
| |
Что здесь происходит:
Сериализатор пишет в StreamWriter
StreamWriter пишет в компрессор BrotliStream
BrotliStream пишет в MemoryStream
TransferUtilityUploadRequest содержит в себе MemoryStream
TransferUtility исполняет TransferUtilityUploadRequest, загружая сериализованный и сжатый объект на S3.
Но перед отправкой на S3 сериализация проходит полностью, в буфер в памяти, MemoryStream. Как бы мне избавиться от буфера и производить всю последовательность "сериализация-сжатие-запись на носитель" на лету, с минимальным использованием промежуточных буферов?
Обновление:
Конкретно с S3 так не получится, потому что S3 так не работает. Но вопрос остаётся прежним — как сделать такой stream, который при чтении будет пополняться сам из указанного источника, пока источник не закончится? С кусками по 4килобайта, например.