我正在创建一个简单的zip程序,可以接收任何文件并从中创建一个霍夫曼树 . 我将每个字节的频率保存在HashMap中,然后根据字节和频率创建霍夫曼树 . 然后,我使用ObjectOutputStream来编写Huffman树节点和包含原始频率的对象以及可以解码霍夫曼树的比特序列 . 运行我的测试文件时,我收到了一个EOF异常 . 我正在关闭我的输出流,但我担心我的代码中有一两个错误导致了这一点 .

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类,它构建Huffman树并构建并获取每个叶节点的路径

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.ObjectInputStream中的java.io.EOFException java.io.ObjectInputStream上的$ PeekInputStream.readFully(ObjectInputStream.java:2335)java.io.ObjectInputStream.readStreamHeader中的BlockDataInputStream.readShort(ObjectInputStream.java:2804)(ObjectInputStream . java:802)at java.io.ObjectInputStream . (ObjectInputStream.java:299)at ZipTest.loadSaved(ZipTest.java:200)at ZipTest.testByteFileCorrectEncodingLength(ZipTest.java:267)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native方法)at 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());
  }