2011-06-03 36 views
5

我有相当数量的可传输数据(> 100MB),为了压缩,我想主机打包在一个zip文件中的http服务器上。所以这个zipfile包含一个文件。Java:通过HTTP传输Zipfile的内容

现在有可能java客户端通过http流式传输数据,即使它被打包在一个zip文件中?

根据维基百科,拉链都没有顺序...

http://en.wikipedia.org/wiki/ZIP_(file_format)#Structure

如果这仍然有可能以某种方式,那么如何?我使用一个自定义的Java客户端(而不是一个webbrowser)是gzip在java http实现中可用吗?

+0

你”重新讨论单独传输zip文件中的文件,而不是整个zip文件的权利? – Alvin 2011-06-07 10:28:37

+0

实际上,zipfile只包含一个文件。这是我想要流的一个。 – clamp 2011-06-07 10:36:40

回答

4

Java支持gzip格式,其中GZipInputStream(解压缩)和GZipOutputStream(压缩)。 zipgzip在内部使用相同的压缩格式,主要区别在于元数据:zip在文件末尾有gzip开头(而gzip只支持一个封闭文件)。

对于流式传输一个大文件,使用gzip将是更好的事情 - 甚至更多,因为您不需要访问元数据。

我不知道,如果HttpConnection的发送Accept-Encoding: gzip,然后自动处理膨胀的内容,如果服务器Content-Encoding: gzip提供,但你一定可以手动如果服务器只需发送的.gz文件用这样做(即Content-Encoding: identity)。

(顺便说一句,确保从不会太小缓冲区流中读取数据,因为每个放气调用将有一个本地调用的开销,因为Java的GZipInputStream使用本地zlib的执行。)

2

是的,你可以,码流的压缩,并使用MIME类型应用程序/压缩

如果你真的想打流音乐在另一端,那么就不能平凡,你可以做只有在整个zip文件在客户端可用时才解压缩。

如果大小是你的关注,你可以拒绝你的MP3比特率或使用格式,如OGG/Vorbis格式

+0

你确定,因为这张图片显示它不是流式传输:http://en.wikipedia.org/wiki/File:ZIPformat.jpg – clamp 2011-06-07 10:14:07

+1

@clamp:你可以流式传输,但是直到你收到客户端文件的全部内容。 (这就是图像/文章所描述的) – sarumont 2011-06-07 14:32:57

+0

@sarumont +1 right – 2011-06-07 18:34:00

4

会更有意义,让web服务器做的压缩和解?如果你只是想减少带宽的量被使用,而不是真的想要存储在服务器上压缩了该文件,这将仅仅是配置的问题,例如见:

http://tomcat.apache.org/tomcat-5.5-doc/config/http.html

用于HTTP/1.1 GZIP压缩。服务器可以强制对客户端的响应进行压缩。请参阅http://en.wikipedia.org/wiki/HTTP_compression

客户端将收到压缩包并处理解压。应该也可以对文件进行流式处理,因此客户端在执行一些有用的操作之前不需要所有文件,因为服务器可以压缩各个块。

+0

我同意@ Ant的基本点 - 如果你有一个单一的文件,使用直接压缩,而不是一个zip压缩文件。只要你喜欢,该文件可以压缩或不在服务器上。 – 2011-06-08 21:25:10

+0

你在这里没有问题。如果你压缩文件,然后在另一端解压,你需要整个zip文件。因此,如果部分在客户端存在,则不能使用zip中的数据。所以基本上,即使zip文件本身正在流式传输,音频本身也不是。我相信解决方案是使用低比特率或更好的流格式 – 2011-06-09 06:59:54

+0

@Suraj如果单个块被压缩,然后不,你没有问题。但确实如此,如果您使用Transfer-Encoding与GZIP压缩一起分块,您需要检查会发生什么情况。潜在地,您只需要使用分块传输编码,然后自行压缩块并将其解压缩到客户端,这很麻烦!我真的不知道它是如何工作,而不尝试它,但我认为个别块将gzipped。如果有人试过,请告诉我! – 2011-06-09 08:58:13

5

下面是一个代码片段(的作品),客户端可以使用从压缩流中读取:

static void processZippedInputStream(InputStream in, String entryNameRegex) 
throws IOException 
{ 
    ZipInputStream zin = new ZipInputStream(in); 
    ZipEntry ze; 
    while ((ze = zin.getNextEntry()) != null) 
    { 
     if (ze.getName().matches(entryNameRegex)) 
     { 
      // treat zin as a normal input stream - ie read() from it till "empty" etc 
      break; 
     } 
     zin.closeEntry(); 
    } 
    zin.close(); 
} 

与正常的InputStream的主要区别是通过迭代的条目。例如,你可能知道你想要第一个条目,所以不需要名称匹配参数等。

+0

正如我所说的那样,zipfile只会包含一个单独的条目。 unforutnately似乎关于这个元信息是在zipfile的最后,所以我需要下载整个文件,然后才能开始解压缩,对吧? – clamp 2011-06-10 08:46:10

+0

否 - 条目遇到名称然后是内容,所以你会得到条目标题 – Bohemian 2011-06-14 08:07:37

0

使用GZIP,然后你可以流。 Gzip无论如何都使用zip的默认压缩算法。

+0

感谢,但是这个gzip在java http实现中可用吗? – clamp 2011-06-10 08:46:27

+0

当然只是发送一个gzipstream,并在服务器端存储流到磁盘。你只是包装当前的流。 gzipstream是POST或PUT中的封闭实体 – MJB 2011-06-10 14:42:28