2016-12-09 17 views
0

Я создаю простую zip-программу, которая может принимать любые файлы и создавать из нее дерево Хаффмана. Я сохраняю частоты каждого байта в HashMap, а затем создаю дерево Хаффмана, основанное на байтах и ​​частотах. Затем я использую ObjectOutputStream для записи как узла дерева Хаффмана, так и объекта, который содержит исходные частоты и битпоследовательности, которые могут декодировать дерево Хаффмана. При запуске моих тестовых файлов я получаю исключение EOF. Я закрываю свои выходные потоки, но, боюсь, у меня есть ошибка или два в моем коде, что вызывает это.Ошибка EOF в программе Huffman Zip

public static void main(String[] args) { 
    if(args.length == 0) 
    { 
     System.out.println("No files provided!"); 
     return; 
    } 
    if(args.length == 1) 
    { 
     System.out.println("Missing at least one file!"); 
     return; 
    } 
    byte[] data = null; 
    String pathname = args[0]; 
    String outputname = args[1]; 

    File initial = new File(pathname); 
    File file = new File(outputname); 

    if(!file.exists()) 
    { 
     try { 
      file.createNewFile(); 
     } catch (IOException e) { 
      System.out.println("Could not create new file"); 
     } 
    } 

    if(!initial.exists()) 
    { 
     System.out.println("This file does not exist"); 
     return; 
    } 

    if(file.canRead() || !initial.canRead()) 
    { 
     System.out.println("Cannot read the file!"); 
     return; 
    } 

    if(!file.canWrite()) 
    { 
     System.out.println("Cannot write to file!"); 
     return; 
    } 


    Path path1 = FileSystems.getDefault().getPath(args[0]); 
    try { 
     data = Files.readAllBytes(path1); 
    } catch (IOException e1) { 
     //Byte data cannot be read 
     e1.printStackTrace(); 
    } 



    // map each byte value to its frequency count 
    HashMap<Byte, Integer> values = new HashMap<Byte, Integer>(); 
    for (byte b : data) { 
     if (values.containsKey(b)) { 
      values.put(b, values.get(b) + 1); // add one to current count 
     } else { 
      values.put(b, 1); 
     } 
    } 
    //Create HuffmanTree 
    Node n = Node.makeHuffmanTree(values); 

    //Initialize BitSequence 
    BitSequence bs = new BitSequence(); 

    //Get final HashMap from HuffmanTreeNode 
    HashMap<Byte, String> map = Node.buildPath(n, "", new HashMap<Byte, String>()); 

    //Iterate through original byte array, append BitSequence 
    String s = ""; 
    for (byte a : data) { 
     s += map.get(a); 
     bs.appendBits(s); 
    } 

    //Create HuffmanSave 
    HuffmanSave hs = new HuffmanSave(bs, values); 

    //Create ObjectOutputStream and FileOutputStream 
    try { 

     //Write the BitSequence and the HuffmanSave to the file 
     ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); 
     oos.writeObject(n); 
     oos.writeObject(hs); 
     oos.close(); 

    } catch (Exception ex) { 
     //Could not write Objects to File 
     ex.printStackTrace(); 

    } 
    //Close the output streams 

} 

Вот мой класс Node, который строит дерево Хаффмана и строит и получает путь к каждому узлу листа

import java.util.HashMap; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.PriorityQueue; 

public class Node implements Comparable<Node> { 
    Node left; 
    Node right; 
    Node parent; 
    static byte bytes; 
    int freq; 

    public Node(byte newbyte, int newfreq) { 
     bytes = newbyte; 
     freq = newfreq; 
    } 

    public Node(int newfreq) { 
     freq = newfreq; 
    } 

    public int compareTo(Node n) { 
     if (freq < n.freq) { 
      return -1; 
     } else if (freq > n.freq) { 
      return 1; 
     } 
     return 0; 
    } 

    public static Node makeHuffmanTree(Map<Byte, Integer> map) { 
     PriorityQueue<Node> queue = new PriorityQueue<Node>(); 
     for (Entry<Byte, Integer> entry: map.entrySet()) { 
      Node n = new Node(entry.getKey(), entry.getValue()); 
      queue.add(n); 
     } 

     Node root = null; 
     while (queue.size() > 1) { 
      Node first = queue.poll(); 
      Node second = queue.poll(); 
      Node combined = new Node(first.freq + second.freq); 
      combined.right = first; 
      combined.left = second; 
      first.parent = combined; 
      second.parent = combined; 
      queue.add(combined); 

      root = combined; 
     } 
     return root; 
    } 

    public static HashMap<Byte, String> buildPath(Node n, String s, HashMap<Byte, String> map) { 
     if (n.left != null) 
     { 
      s += "0"; 
      return buildPath(n.left, s, map); 
     } 
     if (n.right != null){ 
      s += "1"; 
      return buildPath(n.right, s, map); 
     } 
     if (n.left == null && n.right == null) { 
      map.put(bytes, s); 
     } 
     return map; 
    } 
} 

трассировки стека выглядит следующим образом:

java.io.EOFException at java.io.ObjectInputStream $ PeekInputStream.readFully (ObjectInputStream.java:2335) at java.io.ObjectInputStream $ BlockDataInputStream.readShort (ObjectInputStream.java:2804) at java.io.ObjectInputStrea m.readStreamHeader (ObjectInputStream.java:802) на java.io.ObjectInputStream. (ObjectInputStream.java:299) в ZipTest.loadSaved (ZipTest.java:200) на ZipTest.testByteFileCorrectEncodingLength (ZipTest.java:267) на sun.reflect.NativeMethodAccessorImpl.invoke0 (нативный метод) на sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)

метод

ZipTest, который получает сообщение об ошибке:

private HuffmanSave loadSaved(String name) throws IOException, ClassNotFoundException { 
    FileInputStream fileIn = new FileInputStream(new File(name)); 
    ObjectInputStream in; 
    in = new ObjectInputStream(fileIn); 
    HuffmanSave result = (HuffmanSave) in.readObject(); 
    in.close(); 
    fileIn.close(); 
    return result; 
    } 

и метод, вызывает loadSaved()

@Test 
    public void testTextFileCorrectEncodingLength() throws ClassNotFoundException, IOException { 
    Zip.main(new String[] {"mary.txt", "mary.dmz"}); 

    HuffmanSave result = loadSaved("mary.dmz"); 
    assertEquals(227, result.getEncoding().length()); 
    } 
+0

* Я получаю исключение EOF * **, где ** –

+0

Не могли бы вы добавить StackTrace исключения? –

+0

А также добавьте метод 'ZipTest.loadSaved' и указав 200-ю строку в этом методе. –

ответ

1

Возможно, вам понадобится интерфейс java.io.Serializable для ваших Node и HuffmanSave классов.

// Node n = Node.makeHuffmanTree(values); 
// HuffmanSave hs = new HuffmanSave(bs, values); 
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)) 
oos.writeObject(n); 
oos.writeObject(hs); 
oos.close(); 

От Javadoc ObjectOutputStream:

Only objects that support the java.io.Serializable or * java.io.Externalizable interface can be read from streams.