在Java中读取未知长度的Gzip文件

时间:2018-03-15 20:58:18

标签: java java-stream bufferedreader compression gzipinputstream

我要求从s3下载.gz格式的文件。 我可以很好地做到这一点

BufferedInputStream bufferedInputStream = new BufferedInputStream( new GZIPInputStream(fileObj.getObjectContent()));

现在,要阅读此文件的内容,我可能需要做类似这样的事情

    int n;
    byte[] buffer = new byte[1024];
     while ((n = bufferedInputStream.read(buffer)) != -1) {
     }

但是我不知道原始.gz文件的大小。

可能会说我可能从aws-s3-sdk的某些API获得大小。 但我认为必须有更好的方法。

另外,我需要非常快速地进行无压缩。我可以在GZIPInputStream上执行任何等效的Parallel Streaming吗?

1 个答案:

答案 0 :(得分:1)

  

我要求从s3下载.gz格式的文件。一世   可以很好地做到这一点

BufferedInputStream bufferedInputStream = new BufferedInputStream(new
GZIPInputStream(fileObj.getObjectContent()));

首先,所有GZIPInputStream都不将文件内容作为构造参数,而是文件输入流(like this)。

其次,您不一定需要BufferedInputStream,因为您已经可以使用父FileInputStream类的GZIPInputStream.read(buffer[])方法缓冲输入。

第三,在Java中阅读时,您需要知道Gzip文件(或任何其他文件)的大小。这正是xxxInputStream家庭课的全部内容:你只需要知道从哪里开始阅读,但你一定不知道在哪里结束。

所以你的代码看起来像是:

    int megabytesCount = 10;
    try(GZIPInputStream gzipInputStream = new GZIPInputStream(yourFileInputStream))
    {
        bytes[] buffer = new bytes[megabytesCount * 1024];
        int bytesRead = -1;
        if(( bytesRead = gzipInputStream.read(buffer)) = -1)
        {
            // do Something with your buffer and its current size n; 
        }
    }catch(Expection blahBlah){

    }

bufferedInputStream类将从您的文件块中读取最大1024字节的字节(缓冲区数组buffer)。它不会读取最大值或最大值,您不知道。您所知道的是,从您的文件中读取的字节数将保存在变量bytesRead中。如果bytesRead != -1则表示您已从文件中读取了一些数据。只有当您到达bytesRead == -1时,您才知道自己就在文件的末尾。这就是为什么您不需要知道文件的实际大小。只需打开文件/或从aws-s3下载文件并开始阅读。

  

另外,我需要非常快速地进行无压缩。有没有   相当于我可以执行的并行流   GZIPInputStream?

如果您知道设置缓冲区,使用GZIPFileInputStream压缩/解压缩* .gzip文件应该足够快。例如,对于具有1G(1000 * 1024字节)且megabytesCount = 10的文件,您只能访问文件100次。

如果你想更快地移动(如果你的记忆允许它用于你的程序),那么做megabytesCount = 100,你的访问权限将只有10;

如果你必须一个接一个地访问你的数据,那么并行流在这里什么也没带来。