在JAVA 8中读取GZIP文件的字节范围

问题描述 投票:0回答:1

我正在尝试读取Java 8中的gz文件,该文件已被分成块,然后将解压缩的数据(使用BufferedWriter)写入文件。例如: 范围=0-100,范围=101-202,依此类推。

我的第一个问题是:是否可以按照我介绍的方式进行? 我的第二个问题:如果可能的话,我做错了什么?

根据我从其他论坛了解到的信息,我需要一个 GZIPInputStream 和一个 ByteArrayOutputStream 来解压缩字节。我的问题是,在成功写入第一个块(包含 GZIP_HEADER 的块)后,我将收到其余块的此错误:

java.util.zip.ZipException: Not in GZIP format
=> 由于标题不存在

我尝试使用 GZIPOutputStream 基本上重新创建有效的 gz 文件(将 gzipHeader 添加到压缩数据中),但我会收到以下错误:

java.util.zip.ZipException: invalid distance too far back

java.util.zip.ZipException: invalid code lengths set

java.util.zip.ZipException: invalid block type

这是我在主课中尝试过的:

byte[] fileData = Files.readAllBytes(filePath);
System.out.println("File data size: " + fileData.length);
int chunkSize = fileData.length / 5; // dividing the file into 5 equal parts

// Iterate over the chunks
for (int i = 0; i < 5; i++) {
     int startIndex = i * chunkSize;
     int endIndex = Math.min((i + 1) * chunkSize, fileData.length);

     // Extract the chunk from the file data
     byte[] chunk = new byte[endIndex - startIndex];
     System.arraycopy(fileData, startIndex, chunk, 0, endIndex - startIndex);
     if (i != 0) {
        chunk = decompressor.addGzipHeader(chunk);
     }

     try {
        byte[] decompressedData = decompressor.decompress(chunk);
        System.out.println("Successfully written chunk " + i);
        bufferedWriter.write(new String(decompressedData));
     } catch (IOException e) {
        e.printStackTrace();
     }
}
bufferedWriter.close();

这是我在 Decompressor 类中尝试过的:

public byte[] addGzipHeader(byte[] compressedData) throws IOException {
   ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

   // Write gzip header bytes to the ByteArrayOutputStream
   byteArrayOutputStream.write(this.gzipHeader);

   // Write compressed data to the ByteArrayOutputStream
   byteArrayOutputStream.write(compressedData);

   return byteArrayOutputStream.toByteArray();
}
public byte[] decompress(byte[] compressedData) throws IOException {
   byte[] buffer = new byte[1024];

   try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(compressedData);
        GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream)) {
        int bytesRead;
        while ((bytesRead = gzipInputStream.read(buffer)) != -1 && byteArrayInputStream.available() > 0) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
         }
    }
    return byteArrayOutputStream.toByteArray();
}

非常感谢您抽出时间!

java gzip
1个回答
0
投票

在各个部分上使用串联输入流,并用 GZipInputStream 包装它。第一部分包含标题,其他部分不包含。然后,当您创建部件时,您可以按原样获取压缩数据,并将其简单地分区为块(分割文件)。当您组合它们时,您可以使用 SequenceInputStream 按顺序读取它们,以便 GZipInputStream 看到完整文件的所有字节,而不知道有任何部分。

这假设块是通过简单地分割完整文件来创建的,但我相信这是常见的方法。

© www.soinside.com 2019 - 2024. All rights reserved.