获取此GZIPInputStream的未压缩大小?

我有一个GZIPInputStream ,我是从另一个ByteArrayInputStream构造的。 我想知道gzip数据的原始(未压缩)长度。 虽然我可以读到GZIPInputStream的末尾,然后计算数字,它会花费很多时间并浪费CPU。 我想在阅读之前知道尺寸。

对于GZIPInputStream是否有像ZipEntry.getSize()这样的类似方法:

public long getSize ()
自: API级别1
获取此ZipEntry的未压缩大小。

对于GZIPInputStream,是否存在类似ZipEntry.getSize()的类似方法

不,它不在Javadoc =>它不存在。

你需要什么长度

可以通过读取gzip压缩文件的最后四个字节来确定未压缩的大小。

我发现这个解决方案:

http://www.abeel.be/content/determine-uncompressed-size-gzip-file

同样从这个链接有一些示例代码(更正使用long而不是int ,以处理2GB和4GB之间的大小,这将使int包围):

 RandomAccessFile raf = new RandomAccessFile(file, "r"); raf.seek(raf.length() - 4); byte b4 = raf.read(); byte b3 = raf.read(); byte b2 = raf.read(); byte b1 = raf.read(); long val = ((long)b1 << 24) | ((long)b2 << 16) | ((long)b3 << 8) | (long)b4; raf.close(); 

val是以字节为单位的长度。 注意:当未压缩文件大于4GB时,无法确定正确的未压缩大小!

根据@ Alexander的回答:

 RandomAccessFile raf = new RandomAccessFile(inputFilePath + ".gz", "r"); raf.seek(raf.length() - 4); byte[] bytes = new byte[4]; raf.read(bytes); fileSize = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); if (fileSize < 0) fileSize += (1L << 32); raf.close(); 

除了解压缩整个事物之外,没有可靠的方法来获得长度。 使用zlib的gzip文件访问function查看未压缩的文件大小 。

如果你能猜出压缩比(如果数据与你已经处理的其他数据类似的合理期望),那么你可以计算出任意大文件的大小(有一些错误)。 同样,这假定包含单个gzip流的文件。 以下假设第一个大小大于估计大小的90%(基于估计比率)是真实大小:

 estCompRatio = 6.1; RandomAccessFile raf = new RandomAccessFile(inputFilePath + ".gz", "r"); compLength = raf.length(); byte[] bytes = new byte[4]; raf.read(bytes); uncLength = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); raf.seek(compLength - 4); uncLength = raf.readInt(); while(uncLength < (compLength * estCompRatio * 0.9)){ uncLength += (1L << 32); } 

[将estCompRatio设置为0相当于@Alex的答案]

不,不幸的是,如果你想获得未压缩的大小,你必须阅读整个流并增加你在问题中提到的计数器。 为什么你需要知道尺寸? 可以根据您的目的估算尺寸吗?

基于4个尾部字节的更紧凑的计算版本(避免使用字节缓冲区,调用Integer.reverseBytes来反转读取字节的字节顺序)。

 private static long getUncompressedSize(Path inputPath) throws IOException { long size = -1; try (RandomAccessFile fp = new RandomAccessFile(inputPath.toFile(), "r")) { fp.seek(fp.length() - Integer.BYTES); int n = fp.readInt(); size = Integer.toUnsignedLong(Integer.reverseBytes(n)); } return size; }