1

シリアル ポート経由でリモート デバイスに命令を送信し、既知のバイト数を応答として取得する Java メソッドを作成しました。コードは、librxtx-java ライブラリを使用して RaspberryPi で実行されます。リモート デバイスは、予想される長さの応答を送信することが確認されました。

以下のコードは、このメソッドの最後の部分であり、RaspberryPi は指定された時間 "t_max" まで応答のすべてのバイトを待ちます。

そのままのコードでは、 中に IndexOutOfBoundsException がスローされSystem.arraycopyます。arraycopy 命令を try...catch でラップし、catch でポインター変数を出力すると、実際にインデックス オーバーフローが発生します。

ただし、ポインター値を出力する行のコメントを外すと、例外はなくなります。この行を置き換えてもSystem.out.println("X");例外はなくなりますが、System.out.print("X");たとえばそうではありません。

変数を揮発性に変更しようとしましたが、もう運がありません。端末に出力すると、変数の値がどのように変化しますか?

long t0 = System.currentTimeMillis();
long t = t0;
byte[] answer = new byte[answerLength];
byte[] readBuffer = new byte[answerLength];
int numBytes = 0;
int answerPointer = 0;
while (t - t0 < t_max) {
    try {
        if (inputStream.available() > 0) {
            numBytes = inputStream.read(readBuffer);
        }
    } catch (Exception e) {
    }

    if (numBytes > 0) {
        // System.out.println("answerPointer="+answerPointer);
        System.arraycopy(readBuffer, 0, answer, answerPointer, numBytes);
        answerPointer = answerPointer + numBytes;
    }

    if (answerPointer == answerLength) {
        return (answer);
    }

    t = System.currentTimeMillis();
}
4

2 に答える 2

1

出力ストリームと入力ストリームが何らかの方法でリンクされているかどうかを確認しようとしましたか? 入力ストリームが出力ストリームから読み取っていて、'\n' (改行) がストリーム文字の末尾として使用されている可能性があります。標準出力の代わりにバイト配列出力ストリームをラップする印刷ストリームに出力してみて、ps.println("X") を実行すると例外が発生するかどうかを確認できますか? 例外が発生する場合は、標準出力と入力ストリームがリンクされている可能性があり、それが System.out.println("X") を実行すると例外がなくなる理由です。

また、volatileキーワードは、スレッドのコンテキストで使用されます。シングルスレッド環境では効果がありません。

于 2013-10-29T09:10:50.003 に答える