Zlib圧縮にJava.util.ZipのDeflateクラスとInflateクラスを使用しようとしています。
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によって言及されたこれらのようなかなりのマイナーなエラーがあります:
a
も設定せずに、インフレータへの入力を設定します。私が見つけたもう少し:
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 http://stackoverflow.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"));
}
}
効率を上げるには、ファイルストリームをバッファリングされたストリームでラップすると便利な場合があります。これがパフォーマンスに重要な場合は、測定してください。
PaŭloEbermann のコードは、 try-with-resources を使用してさらに改善できます。
import Java.util.Scanner;
import Java.util.Zip.*;
import Java.io.*;
public class ZLibCompression
{
public static void compress(File raw, File compressed) throws IOException
{
try (InputStream inputStream = new FileInputStream(raw);
OutputStream outputStream = new DeflaterOutputStream(new FileOutputStream(compressed)))
{
copy(inputStream, outputStream);
}
}
public static void decompress(File compressed, File raw)
throws IOException
{
try (InputStream inputStream = new InflaterInputStream(new FileInputStream(compressed));
OutputStream outputStream = new FileOutputStream(raw))
{
copy(inputStream, outputStream);
}
}
public static String decompress(File compressed) throws IOException
{
try (InputStream inputStream = new InflaterInputStream(new FileInputStream(compressed)))
{
return toString(inputStream);
}
}
private static String toString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
private static void copy(InputStream inputStream, OutputStream outputStream)
throws IOException
{
byte[] buffer = new byte[1000];
int length;
while ((length = inputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, length);
}
}
}