.net 是否可以将一组文件流式传输到浏览器,因为它们';您正在压缩还是让客户端压缩?

.net 是否可以将一组文件流式传输到浏览器,因为它们';您正在压缩还是让客户端压缩?,.net,file,browser,compression,streaming,.net,File,Browser,Compression,Streaming,背景信息:我正在使用.Net框架和MVC 这是我的困境:我目前正在使用一个服务打开一组文件(来自sql server)。从服务中打开整个文件所需的时间延迟与文件大小成正比。我正在获取此文件,然后将其从我的web应用程序流式传输到web浏览器。正如您可以想象的那样,由于浏览器对任何超过500MB的文件超时(因为在开始流媒体之前花费的时间太长),因此这不是非常可伸缩的。因此,我们使用的解决方案称为数据的“分块”。我从服务中获取64KB的数据片段,然后立即将它们流式传输到浏览器 这对于单个文件非常有效

背景信息:我正在使用.Net框架和MVC

这是我的困境:我目前正在使用一个服务打开一组文件(来自sql server)。从服务中打开整个文件所需的时间延迟与文件大小成正比。我正在获取此文件,然后将其从我的web应用程序流式传输到web浏览器。正如您可以想象的那样,由于浏览器对任何超过500MB的文件超时(因为在开始流媒体之前花费的时间太长),因此这不是非常可伸缩的。因此,我们使用的解决方案称为数据的“分块”。我从服务中获取64KB的数据片段,然后立即将它们流式传输到浏览器


这对于单个文件非常有效,但是,我们有一个要求,即如果有多个文件,则需要将它们压缩到单个文件中。压缩的问题是,我需要从服务下载所有文件,然后才能开始流式传输压缩包。我想我知道这个问题的答案,但我还是要问:有没有一种方法可以在压缩一组文件时对其进行流式处理?我非常怀疑您是否可以,因为压缩算法需要能够看到整个文件。或者,是否有一个JAVASCRIPT软件包可以单独捕获文件(当它们正在流式传输时),然后在流式传输完成后对其进行压缩?如果您能给我一些建议,我将不胜感激

客户端似乎有一个压缩包。注意:您需要下载,然后在用户的计算机上创建文件。不过,它看起来不太受跨浏览器支持,而且在客户端JS中丢弃的数据量可能会导致问题

不发送zip文件,您是否可以查看流式传输不同的存档格式,如或?它将只包含有关文件的元数据,然后是文件数据

或者,您可以借用7digital和Bleep record music stores使用的解决方案,将服务器上的文件压缩到临时目录,同时立即向用户显示页面。该页面在客户端使用一段JS轮询服务器,直到整个文件准备好下载,然后它可以按照正常方式开始下载

更新 我注意到,如果您从DropBox网站下载目录,它会立即开始下载,并且不知道完整的文件大小——这表明它在完成创建归档之前就开始下载了。进一步阅读和建议您可以在从服务获取完整文件数据之前,开始生成压缩数据并将其流式传输到客户端

代码看起来类似于以下未经测试和简化的示例:(使用类名)

如果您希望进一步压缩文件(如果为压缩器提供更大的块,可能会出现这种情况),但也希望尽快进行数据流传输,并且您知道从服务到应用程序的数据比从应用程序到客户机的数据要快,您可以在foreach循环中实现某种指数缓冲区

int chunksPerWrite = 1; // Better if this is defined outside of the foreach loop
byte[] chunk;
var chunks = new List<byte[]>();
while ((chunk = service.GetChunk(filename)).Length > 0) {
     chunks.Add(chunk)

     if (chunks.Count >= chunksPerWrite) {
         // Combine all the chunks with some array copying logic not included
         byte[] megaChunk = CombineAllChunks(chunks);
         zipStream.Write(megaChunk, 0, megaChunk.Length);
         chunksPerWrite *= 2; // or chunksPerWrite++ for a linear growth
     }
}

// Cut for brevity - combine any last chunks and send to the zipStream.
int chunksPerWrite=1;//如果在foreach循环之外定义,则更好
字节[]块;
var chunks=新列表();
while((chunk=service.GetChunk(filename)).Length>0){
添加(块)
if(chunks.Count>=chunksPerWrite){
//将所有块与未包含的某些数组复制逻辑组合在一起
字节[]兆块=组合块(块);
zipStream.Write(兆块,0,兆块,长度);
chunksPerWrite*=2;//或chunksPerWrite++用于线性增长
}
}
//为简洁而剪切-将最后的块合并并发送到zipStream。
我对ZIP规范的阅读表明,在一次压缩中可以有效压缩多少数据是有限制的,但我无法计算出该限制是什么(可能取决于数据?)。我将非常有兴趣听到任何人谁知道规格更好


如果您发现出于某种原因需要自己滚动,Zip文件也有一个简单的存储机制,没有压缩引擎,如果您不关心带宽,它会变得更容易。

太棒了!谢谢您的建议。@TheDude我已经更新了关于流式压缩文件的更多信息-在将压缩数据发送到客户端之前,您不需要下载所有文件数据。我感谢您的更新。我将阅读你链接的那些文章。我实际上是从一个单独的服务下载64KB的文件块。如果一个文件被分成50个64KB的块,我在获取它们时将它们单独压缩,并将其立即流式传输到浏览器,那么单个PACKAGE.zip文件基本上将包含50个单独的压缩块。单个解压算法是如何处理的?有一个付费组件明确表示它可以做到这一点:
int chunksPerWrite = 1; // Better if this is defined outside of the foreach loop
byte[] chunk;
var chunks = new List<byte[]>();
while ((chunk = service.GetChunk(filename)).Length > 0) {
     chunks.Add(chunk)

     if (chunks.Count >= chunksPerWrite) {
         // Combine all the chunks with some array copying logic not included
         byte[] megaChunk = CombineAllChunks(chunks);
         zipStream.Write(megaChunk, 0, megaChunk.Length);
         chunksPerWrite *= 2; // or chunksPerWrite++ for a linear growth
     }
}

// Cut for brevity - combine any last chunks and send to the zipStream.