0

我需要从 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 上执行任何等效的并行流吗?

4

1 回答 1

1

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

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

首先,所有 GZIPInputStream 不是文件内容作为构造函数参数,而是文件输入流(像这样)。

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

第三,在 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;

如果您必须一个接一个地访问您的数据,那么并行流不会带来任何好处。

于 2018-03-17T17:27:27.437 回答