Java动态读取GZIP日志文件时抛出Not in GZIP format异常求助
我需要动态解压日志文件并输出至控制台,但运行时抛出以下异常:
java.util.zip.ZipException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:166) ~[?:?]
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:80) ~[?:?]
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:92) ~[?:?]
我的实现代码如下:
private static void readLogFile(File f) { try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(f)), "UTF-8"))) { String nextLine; while ((nextLine = reader.readLine()) != null) { System.out.println(nextLine); } } catch (FileNotFoundException e) { logger.error("file doesn't exist." ); } catch (IOException e) { logger.error("Error reading the file", e); } }
原日志文件大小约50MB,压缩后的.gz文件为2.4MB,已通过终端成功解压该文件,确认文件未损坏,请问问题出在哪里?
问题排查及解决方案
1. 确认目标文件正确性
检查传入的File f对象是否准确指向那个2.4MB的.gz压缩文件,而非原日志文件或其他非GZIP格式文件。排查是否存在文件重名、路径拼写错误、程序读取了临时缓存文件等情况。
2. 验证GZIP格式兼容性
终端gzip命令支持部分扩展格式,但Java的GZIPInputStream仅严格遵循标准GZIP规范。若压缩文件由非标准工具生成,可能包含额外元数据导致识别失败。可尝试用标准命令重新压缩原日志:
gzip -c original.log > new.log.gz
再用程序读取新生成的new.log.gz测试。
3. 排查流读取异常
磁盘IO临时问题可能导致FileInputStream读取内容不完整,可先将文件完整读取到字节数组,再传入GZIP流:
private static void readLogFile(File f) { try { byte[] fileBytes = Files.readAllBytes(f.toPath()); try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(fileBytes)), "UTF-8"))) { String nextLine; while ((nextLine = reader.readLine()) != null) { System.out.println(nextLine); } } } catch (FileNotFoundException e) { logger.error("file doesn't exist." ); } catch (IOException e) { logger.error("Error reading the file", e); } }
4. 检查文件头部完整性
标准GZIP文件前两个字节固定为1F 8B,可通过hexdump命令查看文件开头:
hexdump -n 2 your-file.log.gz
若输出不是1f8b,说明文件开头存在隐藏字符或BOM头,需清理后再读取。
内容的提问来源于stack exchange,提问作者Watermelon

