我正在创建一个简单的zip程序,可以接收任何文件并从中创建一个Huffman Tree。我将每个字节的频率保存在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.EOFException的 at java.io.ObjectInputStream $ PeekInputStream.readFully(ObjectInputStream.java:2335) at java.io.ObjectInputStream $ BlockDataInputStream.readShort(ObjectInputStream.java:2804) at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802) 在java.io.ObjectInputStream。(ObjectInputStream.java:299) 在ZipTest.loadSaved(ZipTest.java:200) 在ZipTest.testByteFileCorrectEncodingLength(ZipTest.java:267) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 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());
}