2011-05-30 14 views
8

zlib sıkıştırması için java.util.zip dosyasında Deflate and Inflate sınıflarını kullanmaya çalışıyorum.Zlib sıkıştırma Java'da Deflate ve Inflate sınıflarını kullanma

İşte
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) 

şimdiye kadar benim kodudur - - Ne çalıştığınız

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"); 

    } 
} 
+0

bir ev ödevi bu? Bir hata bitirmek çok erken bitiriyor, başka bir setInput w/o uzunluğu kullanıyor ve bir defalık işlemin 1024'ten daha fazla veri döndürüp döndürmediğini kontrol etmiyor. – bestsss

cevap

25

Ben Söndür kullanarak kodu sıkıştırmak mümkün, ama açtıktan ederken, bu hatayı yaşıyorum

burada mı Verilerinizi açan bir InflaterInputStream kullanıyorsunuz ve bu sıkıştırılmış verileri tekrar bir Inflater'e aktarmaya çalışıyorsunuz? Bunlardan birini kullanın, ancak ikisinden de değil.

Bu, özel durumunuza neden olan şeydir. - bittikten sonra, artık veri eklenebilir

  • Sen döngü içinde sıkıştırma bitirmek:

    Buna ek olarak, bestsss bahsettiği bu gibi oldukça bazı küçük hatalar vardır.

  • Deflate işleminin ne kadar üretildiğini kontrol edemezsiniz. Uzun çizgiler varsa, 1024 bayttan fazla olabilir.
  • Girdiyi, a uzunluğunu ayarlamadan da Inflater'e ayarlayabilirsiniz.

buldum hangi Biraz daha:

  • Sen yazdıktan sonra (ve aynı dosyadan okuma önce) FileOutputStream kapatmayın.
  • Bir metin satırını okumak için readLine() kullanıyorsunuz, ancak satır aralığını tekrar eklemiyorsunuz, bu, sıkıştırılmış dosyanızda herhangi bir satır sonu olmayacak demektir.
  • Gereksinim duymadan bayttan dizeye ve bayttan tekrar dönüştürüyorsunuz.
  • Daha sonra kullanmadığınız değişkenler yaratıyorsunuz.

Programınızı düzeltmeye çalışmıyorum. İşte size istediğimi yapan basit bir şey, DeflaterOutputStream ve InflaterInputStream kullanarak. (Ayrıca, yerine JZlib en ZInputStream ve ZOutputStream kullanabilirsiniz.)

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")); 
    } 
} 

Daha fazla verim için tamponlu akışları ile dosya akışlarını sarmak için yararlı olabilir. Bu performans açısından kritikse ölçün.

+0

bunun zlib için olduğundan eminsiniz. Bir zlib dosyasını açmaya çalışıyorum ama bilinmeyen bir sıkıştırma yöntemi hatası alıyorum. Eğer http://docs.oracle.com/javase/1.4.2/docs/api/java/util/zip/package-summary.html adresine bakarsanız, 'Inflater' zlib'den bahseder ama 'InflaterInputStream' kullanırsınız. , sıkıştırma yöntemini azaltır. Bu dosya şu: https://dl.dropboxusercontent.com/u/17630770/temp/pc_oj_simple_AnimTake1_11.icecache.zip – clankill3r

+0

InflaterInputStream, (Inflater parametresi olmayan yapıcıyı kullanıyorsa) bir 'yeni Inflater()' kullanır. Ve bu kurucu zlib sıkıştırması anlamına gelen 'nowrap = false' kullanır. (Dosyanızı kontrol etmedim.) –

4

Paŭlo Ebermann bireyin kodu ayrıca try-with-resources kullanılarak geliştirilebilir:

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); 
     } 
    } 
} 
+0

Tarayıcının amacı nedir? Sadece akışın ilk çizgisini mi aldın? –

+1

@ Paŭlo Ebermann: Bu, tüm akışı bir kerede okumak için bir hiledir – BullyWiiPlaza

İlgili konular