读取distzip压缩文件的最后一行

时间:2018-09-04 06:26:40

标签: java gzip

我正在尝试读取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。我的假设是错误的,认为这行得通吗?还有其他解决方案吗?否则,我会将压缩文件的最后一行存储在单独的文件中。这不理想,但是可以解决问题。

0 个答案:

没有答案