我正在尝试读取dictzip文件的最后一行。 dictzip是一种基于gz的格式,具有块和其他标头信息。
要对此进行存档,我的第一个思想是以下结构:
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file.toFile(), "r")) {
try (RandomAccessInputStream randomAccessInputStream = new RandomAccessInputStream(randomAccessFile)) {
try (DictZipInputStream din = new DictZipInputStream(randomAccessInputStream)) {
long fileLength = din.getLength() - 1;
StringBuilder lastLine = new StringBuilder();
for (long filePointer = fileLength; filePointer != -1; filePointer--) {
din.seek(filePointer);
int readByte = din.read();
if (readByte == 0xA) {
if (filePointer == fileLength) {
continue;
}
break;
} else if (readByte == 0xD) {
if (filePointer == fileLength - 1) {
continue;
}
break;
}
lastLine.append((char) readByte);
}
return lastLine.reverse().toString();
}
}
}
此代码可以工作,但是和解压缩整个文件之前一样慢。 我的下一个想法是跳到dz文件中的最后一块,读取所有字节并占用最后一行。至少这应该比读取整个文件更快。
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file.toFile(), "r")) {
try (RandomAccessInputStream in = new RandomAccessInputStream(randomAccessFile)) {
try (DictZipInputStream din = new DictZipInputStream(in)) {
din.seek(din.getChunkLength() * din.getChunkCount() - 2);
byte[] data = ByteStreams.toByteArray(din);
int fileLength = data.length - 1;
StringBuilder lastLine = new StringBuilder();
int filePointer;
for (filePointer = fileLength; filePointer != -1; filePointer--) {
int readByte = data[filePointer];
if (readByte == 0xA) {
if (filePointer == fileLength) {
continue;
}
break;
} else if (readByte == 0xD) {
if (filePointer == fileLength - 1) {
continue;
}
break;
}
lastLine.append((char) readByte);
}
String result = lastLine.reverse().toString();
return result;
}
}
}
但是此代码抛出EOFException: Unexpected end of ZLIB input stream
。我的假设是错误的,认为这行得通吗?还有其他解决方案吗?否则,我会将压缩文件的最后一行存储在单独的文件中。这不理想,但是可以解决问题。