我收到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位,我认为这不是一般模式。

10-08 15:57