gpt4 book ai didi

c# - 在不使用磁盘的情况下即时压缩流

转载 作者:行者123 更新时间:2023-12-02 20:15:59 32 4
gpt4 key购买 nike

我正在尝试在我的 C# MVC 项目中编写一种方法,该方法从 S3(或任何地方)流式传输文件,并在将压缩流发送给用户之前将其即时压缩为 zip 文件。到目前为止,我已经找到了几种通过将流保存到磁盘然后正常返回它来从流创建 zip 文件的方法,但我想跳过保存到磁盘并使用缓冲区到流的方法。我正在尝试下载一个非常大的文件 (4gb+),该文件很容易压缩到其原始大小的一小部分。

到目前为止,我有这个可以避免磁盘,但似乎首先将整个文件加载到内存中:

using( var memoryStream = new MemoryStream() )
{
using( var archive = new ZipArchive( memoryStream, ZipArchiveMode.Create, true ) )
{
var zipEntry = archive.CreateEntry( File );

using( var entryStream = zipEntry.Open() )
{
S3.StreamFile( File, Bucket ).CopyTo( entryStream );
}
}

return base.File( memoryStream.ToArray(), "application/zip", File + ".zip" );
}

类似的问题 ( Creating a ZIP Archive in Memory Using System.IO.Compression) 只有涉及写入磁盘的答案。

最佳答案

ZipArchive 类需要一个提供当前位置的流。 TrackablePositionStream 下面的类在发生写入调用时通过递增字段来保存位置

public class TrackablePositionStream : Stream
{
private readonly Stream _stream;

private long _position = 0;

public TrackablePositionStream(Stream stream)
{
this._stream = stream;
}

public override void Flush()
{
this._stream.Flush();
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}

public override void SetLength(long value)
{
throw new NotImplementedException();
}

public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}

public override void Write(byte[] buffer, int offset, int count)
{
this._position += count;
this._stream.Write(buffer, offset, count);
}

public override bool CanRead => this._stream.CanRead;

public override bool CanSeek => this._stream.CanSeek;

public override bool CanWrite => this._stream.CanWrite;

public override long Length => this._stream.Length;

public override long Position
{
get
{
return this._position;
}
set
{
throw new NotImplementedException();
}
}
}

然后在你的操作方法中使用它:

using( var archive = new ZipArchive(new TrackablePositionStream(response.OutputStream), ZipArchiveMode.Create, true ) )
{
var zipEntry = archive.CreateEntry( File );

using(var entryStream = zipEntry.Open() )
{
S3.StreamFile( File, Bucket ).CopyTo( entryStream );
}
}

return new EmptyResult();

关于c# - 在不使用磁盘的情况下即时压缩流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52376130/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com