6

ファイルに値を書き込んでいます。

値は正しく書かれています。別のアプリケーションでは、例外なくファイルを読み取ることができます。

しかし、私の新しいアプリケーションでは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());
        }
    }
}
4

2 に答える 2

8

java.nio.ByteBufferのドキュメントから:

例外: BufferUnderflowException - このバッファに残っているバイト数が 8 バイト未満の場合

これで、例外がどこから来ているのかがかなり明確になると思います。これを修正するには、1 バイトのみをチェックするremaining()のではなく、ダブル (8 バイト) を読み取るために ByteBuffer に十分なデータがあることを確認する必要があります。hasRemaining()

while (mappedByteBufferOut.remaining() >= 36) {//36 = 4 * 8(double) + 1 * 4(int)
于 2013-12-17T21:09:06.733 に答える
3

使えるDoubleときに使わないdouble

あなたの問題は、ループの開始時にバイトが残っていることだと思いますが、バイト数を確認しておらず、十分ではありません。

また、正しいバイト エンディアンがあることも確認します。デフォルトはビッグ エンディアンです。

于 2013-12-17T21:02:07.647 に答える