我正在尝试用Java实现一个侦听器,它将侦听System.in,读取已使用Deflate压缩的数据,解压缩数据,然后将其写入System.out。
我想实时处理流式传输到System.in的数据,因此我需要在解压缩数据时保持套接字连接和输入流打开。逐行读出解压缩数据也很重要。我已经实现了以下代码来从压缩流中读取并写入新的输出流:
InputStream inputStream = System.in;
InflaterInputStream inflaterInputStream = new InflaterInputStream(inputStream);
BufferedReader reader = new BufferedReader(new InputStreamReader(inflaterInputStream));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
我正在使用以下Linux命令测试代码:
cat file_with_compressed_data.txt | java Inflate > outputFile.txt
Inflate是我的System.in监听器类。但是,运行此命令时,我收到以下异常:
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:223)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:158)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at Inflate.main(Inflate.java:30)
解压缩似乎正在起作用,因为outputFile.txt包含大多数原始的解压缩数据。但是,outputFile.txt中缺少原始文件中的一些行。
我无法理解为什么会抛出此异常。有没有其他方法可以实时解压缩Deflated数据而不关闭我的输入流?
我的java版本是:
java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) 64-bit Server VM (build 20.8-b03, mixed mode)
可以使用以下方法创建压缩文件:
DeflaterOutputStream out = new DeflaterOutputStream(System.out);
int c;
while ((c = System.in.read()) != -1) {
out.write(c);
}
out.flush();
out.close();
答案 0 :(得分:0)
经过一番调查后,我找到了问题的解决方案。我看起来好像是导致问题的BufferedReader,虽然我必须承认我仍然不明白为什么。我用StringBuilder替换了BufferedReader来生成:
InputStream inputStream = System.in;
InflaterInputStream inflaterInputStream = new InflaterInputStream(inputStream);
StringBuilder toReturn = new StringBuilder();
int c;
while ((c = inflaterInputStream.read()) != -1) {
toReturn.append((char) c);
if ((char) c == '\n') {
System.out.println(toReturn.toString());
toReturn.setLength(0);
}
}