2011-05-30 16 views
8

मैं zlib संपीड़न के लिए java.util.zip में Deflate और Inflate कक्षाओं का उपयोग करने का प्रयास करना चाहता हूं।ज़्लिब संपीड़न जावा में डिफ्लेट और इन्फ्लेट कक्षाओं का उपयोग

मैं Deflate का उपयोग कर कोड को संपीड़ित करने में सक्षम हूँ, लेकिन जब decompressing, मैं इस त्रुटि हो रहा है -

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

    } 
} 
+0

एक होमवर्क है? एक गलती बहुत जल्दी खत्म हो रही है, दूसरा दूसरा setInput w/o लंबाई का उपयोग कर रहा है और एक और यह जांच नहीं कर रहा है कि डिफ्लेट प्रक्रिया 1024 से अधिक डेटा लौटा दी है। – bestsss

उत्तर

25

क्या आप की कोशिश कर रहे यहाँ करो आप एक InflaterInputStream, जो आपके डेटा decompresses उपयोग करते हैं, और फिर आप एक inflater लिए पुन: इस decompressed डेटा पास करने के लिए प्रयास करें? उनमें से एक का प्रयोग करें, लेकिन दोनों नहीं।

यही आपके अपवाद का कारण बन रहा है। - खत्म करने के बाद, कोई और अधिक डेटा जोड़ा जा सकता है

  • आप पाश में संपीड़न खत्म:

    इस के अलावा, काफी कुछ मामूली त्रुटियों, इन bestsss ने उल्लेख की तरह देखते हैं।

  • आप की जांच नहीं करते कितना उत्पादन Deflate प्रक्रिया पैदा करता है। यदि आपके पास लंबी लाइनें हैं, तो यह 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")); 
    } 
} 

अधिक दक्षता के लिए, यह बफ़र धाराओं के साथ फ़ाइल धाराओं रैप करने के लिए उपयोगी हो सकता है। यदि यह प्रदर्शन महत्वपूर्ण है, तो इसे मापें।

+0

क्या आप वाकई zlib के लिए हैं। मैं एक zlib फ़ाइल को डिकंप्रेस करने का प्रयास करता हूं लेकिन मुझे 'अज्ञात संपीड़न विधि' त्रुटि मिलती है। अगर मैं http://docs.oracle.com/javase/1.4.2/docs/api/java/util/zip/package-summary.html तो देखो मैं देख 'Inflater' उल्लेख zlib लेकिन आप InflaterInputStream' का उपयोग' जो उल्लेख संपीड़न विधि deflate। यह फ़ाइल है: https://dl.dropboxusercontent.com/u/17630770/temp/pc_oj_simple_AnimTake1_11।icecache.zip – clankill3r

+0

InflaterInputStream उपयोग करता है (यदि इन्फ्लैटर पैरामीटर के बिना कन्स्ट्रक्टर का उपयोग कर रहा है) एक 'नया इन्फ्लोटर() '। और यह कन्स्ट्रक्टर 'nowrap = false' का उपयोग करता है, जिसका अर्थ है zlib-compression। (मैंने आपकी फाइल नहीं देखी है।) –

4

Paŭlo Ebermann के कोड आगे 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); 
     } 
    } 
} 
+0

स्कैनर का लक्ष्य क्या है? बस धारा की पहली पंक्ति हो रही है? –

+1

@ पालो एबरमान: यह पूरी स्ट्रीम को एक बार में पढ़ने की चाल है – BullyWiiPlaza

संबंधित मुद्दे