在Java中使用Deflate和Inflate类进行Zlib压缩

| 我想尝试将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
来设置充气机的输入。 我发现了一些: 写入后(和从同一文件读取之前),请不要关闭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 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);
        }
    }
}
    

要回复问题请先登录注册