假设我有一个WCF方法
[OperationContract]
bool UploadFile(Stream stream);
如何在stream
上获得Seek功能?
我需要它满足两个要求:
- 读取流的前四个字节以确定文件类型是否具有
50 4B 03 04
ZIP文件签名,并倒带(stream.Seek(0, SeekOrigin.Begin)
) - 从流
ZipFile zip = ZipFile.Read(stream)
读取DotNetZipIonic.Zip.ZipFile
(需要流可查找)
正如CodeCaster所提到的,您无法查找WCF流。你必须使用不同的方法来解决你的问题:
-
为了查看流的头,我读取了流的前四个字节,然后使用类似
ConcatenatedStream
的东西来连接可以放入MemoryStream
中的前四个字节和原始WCF流的其余部分。这将基本上缓冲流的一部分,但级联的流仍然呈现在位置0的流,而不需要查找。 -
如果DotNetZip需要查找功能,那么它需要访问文件的任何部分。您需要将整个WCF流读取到MemoryStream中,并将其提供给DotNetZip。一个更有效的替代方案是编写自己的
Stream
包装类,该类将只缓冲到已请求的最高流位置,这样,如果DotNetZip只在文件的第一个兆字节中查找,则只缓冲一个兆字节的数据(而不是整个50GB文件)。
我发现各种来源声称您无法在WCF中查找流。
应该是这样的,因为最终您的数据将通过网络套接字发送,而网络套接字在设计上不支持查找(它只发送字节数组)。
MemoryStream ms = new MemoryStream();
request.FileByteStream.CopyTo(ms);
s.Position = 0;
var zip = Ionic.Zip.ZipFile.Read(ms)
按行解释代码
- 为zip库创建新的备忘录团队
- 从http请求字节流"请求"复制到内存流
- 由于复制,流的位置现在位于流的末尾,所以请将其找回起始位置
- 实际上在内存流上调用zip,完成
这个额外的步骤是需要的,因为离子zip不支持直接在流上工作