我正在尝试读取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();
}
非常感谢您抽出时间!
在各个部分上使用串联输入流,并用 GZipInputStream 包装它。第一部分包含标题,其他部分不包含。然后,当您创建部件时,您可以按原样获取压缩数据,并将其简单地分区为块(分割文件)。当您组合它们时,您可以使用 SequenceInputStream 按顺序读取它们,以便 GZipInputStream 看到完整文件的所有字节,而不知道有任何部分。
这假设块是通过简单地分割完整文件来创建的,但我相信这是常见的方法。