【发布时间】:2017-06-16 20:00:09
【问题描述】:
我有一个简单的http server,人们在其中上传文件,我只是压缩它们并将它们保存到磁盘。这就是我正在做的我认为人们会更好地理解代码
/// <summary>
/// Client uploads files through here
/// </summary>
private static void Server_ProcessRequest(HttpListenerContext context)
{
// I know that context.Request.InputStream starts like: ------WebKitFormBoundaryePkpFF7tjBAqx29L
// and it also ends with that boundary
// 1. I read from context.Request.InputStream and skip the headers
// (I read until I find 4 new lines)
// 2. I then write the file to disk
// var sizeOfFile = context.Request.ContentLength64;
// etc... read from stream
// 3. create a new stream in order to compress file later
var newStream = System.IO.File.Open("FileJustCreated");
// 4. MySealedLibraryThatICannotModify.CompressFile(newStream,"CompressedFileLocation.zip");
}
所以我在这里的问题是如何避免将文件写入磁盘?我无法将 context.Request.InputStream 传递给压缩文件的方法,因为它包含标题和其他不属于的内容的文件。如果我可以创建一个返回新流的方法,那就太好了。 文件可能很大,我不想将所有内容都保存在内存中,所以我希望创建一个类似 System.IO.File.OpenRead 的方法,它返回一个流,其中只有您读取的部分在内存中.
我知道我可以使用不同的库来压缩文件,但如果我坚持使用这个库并学习新东西会很好。
【问题讨论】:
-
这里的典型方法是将一个流与另一个(自定义)流包装在一起,该流跟踪消耗的字节数并拒绝发布超过此点的数据。您通常会在包装之前将原始流消耗到所需的点。如果有帮助的话,我可能可以从古代历史中挖掘出一个实现......(我曾经在 protobuf-net 中做到这一点)
-
呸,挖了一些东西,但是:
SubStream.cs:github.com/mgravell/protobuf-net/blob/… -
为什么不能简单地将部分读取的流传递给
CompressFile?它实际上是否在阅读之前将流重置为开始?我想你可以直接跳到你想开始使用原始流的地方并传入它,假设它以合理合理的方式读取它。 -
@Servy 通常问题不是在正确的位置开始;它在正确的地方停止。如果意图是“从我们所在的位置读取到文件末尾”,那么可以肯定:不需要额外的东西 - 只需传递现有的流
-
@MarcGravell 这个问题询问如何跳过标题,我认为这将是一开始的。这个问题给我的印象是,要跳过的流部分都在开头,而不是结尾或给定伪代码的中间某处(它跳过了一些行,然后只是将流的其余部分写入磁盘,并且然后到第 3 方图书馆)。对于 OP,如果您在开始时需要跳过的不仅仅是数据,您能否在问题中澄清这一点?
标签: c# stream memorystream httpserver