1

我正在将值写入文件。Bufferunderflowexception Java

这些值写入正确。在另一个应用程序中,我可以无任何例外地读取文件。

但是在我的新应用程序中,当试图读取文件时,我得到一个Bufferunderflowexception

我已经花了好几天的时间来解决这个问题,但我不知道如何解决它。

也做了很多研究。

bufferunderflowexception是指:

Double X1 = mappedByteBufferOut.getDouble(); //8 byte (double) 

这是我的代码读取文件:

@Override 
    public void paintComponent(Graphics g) { 

    RandomAccessFile randomAccessFile = null; 
    MappedByteBuffer mappedByteBufferOut = null; 
    FileChannel fileChannel = null; 

    try { 
     super.paintComponent(g); 

     File file = new File("/home/user/Desktop/File"); 

     randomAccessFile = new RandomAccessFile(file, "r"); 

     fileChannel = randomAccessFile.getChannel(); 

     mappedByteBufferOut = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, randomAccessFile.length()); 

     while (mappedByteBufferOut.hasRemaining()) { 

      Double X1 = mappedByteBufferOut.getDouble(); //8 byte (double) 
      Double Y1 = mappedByteBufferOut.getDouble(); 
      Double X2 = mappedByteBufferOut.getDouble(); 
      Double Y2 = mappedByteBufferOut.getDouble(); 
      int colorRGB = mappedByteBufferOut.getInt(); //4 byte (int) 
      Color c = new Color(colorRGB); 

      Edge edge = new Edge(X1, Y1, X2, Y2, c); 

      listEdges.add(edge); 

     } 
     repaint(); 

     for (Edge ed : listEdges) { 
      g.setColor(ed.color); 
      ed = KochFrame.edgeAfterZoomAndDrag(ed); 
      g.drawLine((int) ed.X1, (int) ed.Y1, (int) ed.X2, (int) ed.Y2); 
     } 
    } 
    catch (IOException ex) 
    { 
     System.out.println(ex.getMessage()); 
    } 
    finally 
    { 
     try 
     { 
      mappedByteBufferOut.force(); 
      fileChannel.close(); 
      randomAccessFile.close(); 
      listEdges.clear(); 
     } catch (IOException ex) 
     { 
      System.out.println(ex.getMessage()); 
     } 
    } 
} 

我希望有人能帮助我。

+0

如果( randomAccessFile.length()> 8){ \t \t而(mappedByteBufferOut.hasRemaining()){ \t \t} } – ImGeorge

回答

4

从java.nio.ByteBuffer中的docs

抛出: BufferUnderflowException - 如果是留在这个缓冲区少于八个字节

我认为这使得它非常清楚哪里这是异常来自。为了解决这个问题,你需要的不是hasRemaining(),以确保字节缓冲区是为了读双(8个字节)在它足够的数据只检查一个字节:

while (mappedByteBufferOut.remaining() >= 36) {//36 = 4 * 8(double) + 1 * 4(int) 
2

我不会用Double时,你可以使用double

我怀疑你的问题是,你必须留在循环的开始字节,但是你没有检查有多少字节,并且没有足够。

我也会确保你有正确的字节序列,默认是大端。

+0

更改双加倍,感谢。 当有足够的字节时,我应该如何继续循环? – Swag

+0

您即将读取36个字节,您可以检查'remaining()> = 36' –