Java 如何将未压缩的InputStream转换为gzip';高效地输入流?

Java 如何将未压缩的InputStream转换为gzip';高效地输入流?,java,gzip,blob,inputstream,outputstream,Java,Gzip,Blob,Inputstream,Outputstream,用户将一个大文件上传到我的网站,我想gzip文件并将其存储在blob中。所以我有一个未压缩的InputStream,而blob需要一个InputStream。我知道如何使用gzipoutstream将InputStream压缩为Outputstream,但是如何从gzip的Outputstream返回blob所需的InputStream 我能找到的唯一方法是使用ByteArrayOutputStream,然后使用toByteArray创建一个新的InputStream。但这意味着我在内存中有一份

用户将一个大文件上传到我的网站,我想gzip文件并将其存储在blob中。所以我有一个未压缩的InputStream,而blob需要一个InputStream。我知道如何使用gzipoutstream将InputStream压缩为Outputstream,但是如何从gzip的Outputstream返回blob所需的InputStream


我能找到的唯一方法是使用ByteArrayOutputStream,然后使用toByteArray创建一个新的InputStream。但这意味着我在内存中有一份完整的文件副本。如果JDBC驱动程序实现也将流转换为字节[],那么我在内存中就有两个副本,这也不会让我感到惊讶。

如果您使用的是java 1.6,那么可以使用
java.util.zip.DeflaterInputStream
。据我所知,这正是你想要的。如果不能使用1.6,则应该能够使用
java.util.zip.Deflater
重新实现
DeflaterInputStream
。从BLOB读回数据时,使用
充气输入流
作为过滤器,以获取原始数据。

如果不希望将整个文件存储在内存中,请写入文件。在我看来,gzip的数据需要去某个地方。我希望直接流到blob中,这样我就不必把整个东西都存储在内存中了。看起来这行不通,因为我需要在设置blob参数时知道长度。我想从技术上讲,我可以流式传输到一个文件,获得文件的大小,然后将其作为输入流返回到blob中,这样我就不需要将整个内容保存在内存中。在这种情况下,我基本上会使用文件系统作为我的内存,这可能会很有用。我不知道那个类。这看起来是正确的解决方案。不幸的是,Blob实现使用长度,DeflaterInputStream始终返回0或1。我认为,我需要长度这一事实意味着,无论发生什么情况,我都无法将数据压缩并直接流式传输到blob中,因为在压缩完成之前,长度是未知的。@Brian,所以在创建blob时,您需要将长度与输入流一起传递?InputStream上没有length方法,只有一个可用的方法,它的意思与流长度完全不同。available()似乎在原始输入流(来自http post)上返回正确的长度。也许它是基于内容长度,或者可能它实际上是在我得到它之前在上游某个地方读取整个流。但是一旦我压缩了它,那就没什么用了,因为在我处理完整个流之前,我不知道压缩的大小,在这一点上它在内存中,所以我可以把它转换成一个字节[]。在这一点上,你在处理时间/空间的折衷。您可以咬紧牙关,压缩到字节数组,使用更多内存,但占用的时间更少。另一种方法是创建一个deflate流,跳过整个过程,找出压缩版本的字节数,然后重新创建deflate流并将其传递给blob,使用更少的内存,但需要更多的时间。