Прочитать последнюю строку сжатого distzip файла - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь прочитать последнюю строку файла 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. Мое предположение неверно, что это будет работать? Есть ли другое решение? В противном случае я буду хранить последнюю строку сжатого файла в отдельном файле. Это не идеально, но сработает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...