我收到NullPointerException,我不知道为什么会发生,也许有人有了新的观点就可以帮我摆脱它!
错误发生在第53行:
if(aHuffmanTreesNode.isAHuffmanLeaf())
当我尝试确定节点是否为霍夫曼树的落叶时。
对于较小的压缩文件,有时可以正常工作,但大多数情况下会引发NullPointer异常。
public class Uncompress {
private HuffNode globalTree;
private HuffNode aHuffmanTreesNode;
private ObjectInputStream objectInputStream;
private DataOutputStream dataOutputStream;
private FHeader fileHeader;
private long numberOfBytesWritten;
public Uncompress(ObjectInputStream ois){
objectInputStream = ois;
numberOfBytesWritten = 0;
}
public void decodeIt (byte[] bytesArray) throws IOException
{
int actualPosition;
byte byteToBeWritten;
for(int i = 0; i < bytesArray.length; i++)
{
byte currentByte = bytesArray[i];
for(int x = 7; x >= 0; x--)
{
if(((currentByte >>> x) & 0x1) == 0)
{
aHuffmanTreesNode = aHuffmanTreesNode.getLeftChildNode();
} else {
aHuffmanTreesNode = aHuffmanTreesNode.getRightChildNode();
}
if(aHuffmanTreesNode.isAHuffmanLeaf())
{
actualPosition = aHuffmanTreesNode.getPosition();
if (actualPosition >= 128)
{
byteToBeWritten = (byte) (actualPosition - 256);
} else
{
byteToBeWritten = (byte) actualPosition;
}
dataOutputStream.writeByte(byteToBeWritten);
numberOfBytesWritten++;
if (numberOfBytesWritten == fileHeader.getTheHeaderLength())
{
return;
}
aHuffmanTreesNode = globalTree;
}
}
}
}
public void openAndDecodeAFile(String path) throws IOException
{
byte[] bytesArray;
headerReader(path);
int datasLength = objectInputStream.available();
while (datasLength > 0)
{
bytesArray = new byte[datasLength];
objectInputStream.read(bytesArray);
decodeIt(bytesArray);
datasLength = objectInputStream.available();
}
objectInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
}
private void headerReader(String path)
{
try {
fileHeader = (FHeader) objectInputStream.readObject();
dataOutputStream = new DataOutputStream(new FileOutputStream(path + fileHeader.getNameOfTheOriginalFile()));
globalTree = fileHeader.getGlobalTree();
aHuffmanTreesNode = globalTree;
}
catch (IOException io)
{
JOptionPane.showMessageDialog(null, "Erreur de lecture de l'entête !","Erreur !", JOptionPane.ERROR_MESSAGE);
io.printStackTrace();
}catch (ClassNotFoundException cnfe)
{
JOptionPane.showMessageDialog(null, "Problème de conversion !","Erreur !", JOptionPane.ERROR_MESSAGE);
}
}
}
这是我的霍夫曼节点类:
public class HuffNode implements Serializable {
private HuffNode leftChildNode;
private HuffNode rightChildNode;
private transient int frequence;
private transient String code;
private int position;
public HuffNode()
{
frequence = 0;
position = -1;
code = "";
}
public HuffNode( int actualPosition)
{
frequence = 0;
code = "";
position = actualPosition;
}
public HuffNode getLeftChildNode()
{
return leftChildNode;
}
public void setLeftChildNode(HuffNode childNode)
{
leftChildNode = childNode;
}
public HuffNode getRightChildNode()
{
return rightChildNode;
}
public void setRightChildNode(HuffNode childNode)
{
rightChildNode = childNode;
}
public int getFrequence()
{
return frequence;
}
public void setFrequence(int freq)
{
frequence = freq;
}
public int getPosition()
{
return position;
}
public void setPosition(int p)
{
position = p;
}
public String getCode()
{
return code;
}
public void setCode(String c)
{
this.code = c;
}
public boolean isAHuffmanLeaf()
{
if(leftChildNode == null && rightChildNode == null)
{
return true;
}else {
return false;
}
}
public void frequenceIncreaseByOne()
{
frequence++;
}
}
和FHeader类:
public class FHeader implements Serializable {
private HuffNode globalTree;
private long numberOfBytes;
private String nameOfTheOriginalFile;
public FHeader (String nof, HuffNode ght, long nob)
{
nameOfTheOriginalFile = nof;
numberOfBytes = nob;
this.globalTree = ght;
}
public String getNameOfTheOriginalFile()
{
return nameOfTheOriginalFile;
}
public long getNumberOfBytes()
{
return numberOfBytes;
}
public HuffNode getGlobalTree()
{
return globalTree;
}
public long getTheHeaderLength()
{
long sizeOfTheHeader = -1;
try {
File tempHeaderFile = new File("tmpHead.tmp");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tempHeaderFile))) {
oos.writeObject(this);
oos.flush();
oos.close();
}
sizeOfTheHeader = tempHeaderFile.length();
tempHeaderFile.delete();
}catch (IOException ex)
{
JOptionPane.showMessageDialog(null,"Un problème est survenu lors de la lecture de l'entête !", "Erreur!", JOptionPane.ERROR_MESSAGE);
}
return sizeOfTheHeader;
}
}
这是堆栈跟踪:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at projet.huffman.Uncompress.decodeIt(Uncompress.java:54)
at projet.huffman.Uncompress.openAndDecodeAFile(Uncompress.java:102)
at projet.huffman.Huffman.launchTaskButtonActionPerformed(Huffman.java:313)
at projet.huffman.Huffman.access$100(Huffman.java:23)
at projet.huffman.Huffman$2.actionPerformed(Huffman.java:91)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
谢谢 !
最佳答案
我认为有两种可能性:
您的霍夫曼构造代码中存在一些错误,并且globalTree
的结构错误。
您尝试解码的输入文件中有一些无效字节。
您可以通过启动调试器并检查globalTree
的结构来验证第一个问题。
要解决第二个问题,您可以简单地在if
之前放置if(aHuffmanTreesNode.isAHuffmanLeaf())
语句以提示输入:
if(aHuffmanTreesNode == null) {
System.err.println("invalid bytes!");
return;
}
顺便说一句,您的代码有点奇怪,因为使用
for(int x = 7; x >= 0; x--)
,您假设所有输入数据都充满8位,我认为这不是一般模式。