我想尝试使用java.util.zip中的Deflate和Inflate类进行zlib压缩.
我能够使用Deflate压缩代码,但在解压缩时,我遇到了这个错误 –
Exception in thread "main" java.util.zip.DataFormatException: unknown compression method
at java.util.zip.Inflater.inflateBytes(Native Method)
at java.util.zip.Inflater.inflate(Inflater.java:238)
at java.util.zip.Inflater.inflate(Inflater.java:256)
at zlibCompression.main(zlibCompression.java:53)
这是我目前的代码 –
import java.util.zip.*;
import java.io.*;
public class zlibCompression {
/**
* @param args
*/
public static void main(String[] args) throws IOException, DataFormatException {
// TODO Auto-generated method stub
String fname = "book1";
FileReader infile = new FileReader(fname);
BufferedReader in = new BufferedReader(infile);
FileOutputStream out = new FileOutputStream("book1out.dfl");
//BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename));
Deflater compress = new Deflater();
Inflater decompress = new Inflater();
String readFile = in.readLine();
byte[] bx = readFile.getBytes();
while(readFile!=null){
byte[] input = readFile.getBytes();
byte[] compressedData = new byte[1024];
compress.setInput(input);
compress.finish();
int compressLength = compress.deflate(compressedData, 0, compressedData.length);
//System.out.println(compressedData);
out.write(compressedData, 0, compressLength);
readFile = in.readLine();
}
File abc = new File("book1out.dfl");
InputStream is = new FileInputStream("book1out.dfl");
InflaterInputStream infl = new InflaterInputStream(new FileInputStream("book1out.dfl"), new Inflater());
FileOutputStream outFile = new FileOutputStream("decompressed.txt");
byte[] b = new byte[1024];
while(true){
int a = infl.read(b,0,1024);
if(a==0)
break;
decompress.setInput(b);
byte[] fresult = new byte[1024];
//decompress.in
int resLength = decompress.inflate(fresult);
//outFile.write(b,0,1);
//String outt = new String(fresult, 0, resLength);
//System.out.println(outt);
}
System.out.println("complete");
}
}
解决方法:
你想在这做什么?您使用InflaterInputStream解压缩数据,然后尝试将此解压缩数据再次传递给Inflater?使用其中任何一个,但不能同时使用两个.
这就是导致你的例外的原因.
除此之外,还有一些小错误,比如bestsss提到的这些错误:
>您在循环中完成压缩 – 完成后,不能再添加数据.
>您不检查放气过程产生的输出量.如果您有长行,则可能超过1024个字节.
>您也可以在不设置长度a的情况下将输入设置到Inflater.
我发现了一些:
>写入后(以及从同一文件读取之前)不要关闭FileOutputStream.
>您使用readLine()读取一行文本,但之后不再添加换行符,这意味着在解压缩文件中不会出现任何换行符.
>无需任何需要,您可以从字节转换为字符串并再次转换为字节.
>您创建以后不使用的变量.
我不会试图纠正你的程序.这是一个使用DeflaterOutputStream和InflaterInputStream完成我认为你想要的东西. (您也可以使用JZlib的ZInputStream和ZOutputStream.)
import java.util.zip.*;
import java.io.*;
/**
* Example program to demonstrate how to use zlib compression with
* Java.
* Inspired by https://*.com/q/6173920/600500.
*/
public class ZlibCompression {
/**
* Compresses a file with zlib compression.
*/
public static void compressFile(File raw, File compressed)
throws IOException
{
InputStream in = new FileInputStream(raw);
OutputStream out =
new DeflaterOutputStream(new FileOutputStream(compressed));
shovelInToOut(in, out);
in.close();
out.close();
}
/**
* Decompresses a zlib compressed file.
*/
public static void decompressFile(File compressed, File raw)
throws IOException
{
InputStream in =
new InflaterInputStream(new FileInputStream(compressed));
OutputStream out = new FileOutputStream(raw);
shovelInToOut(in, out);
in.close();
out.close();
}
/**
* Shovels all data from an input stream to an output stream.
*/
private static void shovelInToOut(InputStream in, OutputStream out)
throws IOException
{
byte[] buffer = new byte[1000];
int len;
while((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
/**
* Main method to test it all.
*/
public static void main(String[] args) throws IOException, DataFormatException {
File compressed = new File("book1out.dfl");
compressFile(new File("book1"), compressed);
decompressFile(compressed, new File("decompressed.txt"));
}
}
为了提高效率,使用缓冲流包装文件流可能很有用.如果这是性能关键,请测量它.