Я создаю простую 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());
}
* Я получаю исключение EOF * **, где ** –
Не могли бы вы добавить StackTrace исключения? –
А также добавьте метод 'ZipTest.loadSaved' и указав 200-ю строку в этом методе. –