Java アプリケーションから USB 接続を介して、反対側の Arduino にデータをプッシュしています。
Arduino は最後に 64 バイトのデータしかバッファリングできないため、Java アプリからの「一口」ごとに送信されるバイト数を制限する必要があります (余分なバイトは失われます)。Arduino コードは、より多くのバイトを受信する準備ができると、単純な ping をワイヤに送信します。
そのため、実際の出力ストリームをラップBufferedOutputStream
する classを拡張しました。ArduinoBufferedOutputStream
Java アプリのさまざまな部分から、任意のバイト数が ( を使用してwrite(byte b)
) ストリームに書き込まれ、ストリームはときどきflush
編集されます。
私が必要なのは(私が推測する) BufferedOutputStream
s flush メソッドをオーバーライドして、Arduino から ping を受信する前に 64 バイトを超えて送信しないようにすることです。その時点で、ストリームはさらに 64 バイト (またはそれ以下) を送信する必要があります。
static class ArduinoBufferedOutputStream extends BufferedOutputStream {
public static final int WIRE_CAPACITY = 25;
private byte[] waiting = new byte[0];
private int onWire = 0;
public ArduinoBufferedOutputStream(final OutputStream wrapped) throws IOException {
super(wrapped, 500);
}
public void ping() {
this.onWire = 0;
this.flush();
}
@Override
public void flush() throws IOException {
if (this.onWire >= WIRE_CAPACITY) {
return; // we're exceeding capacity, don't to anything before the next ping
}
if (this.count > WIRE_CAPACITY) {
this.waiting = new byte[this.count - WIRE_CAPACITY];
System.arraycopy(this.buf, WIRE_CAPACITY, waiting, 0, this.count - WIRE_CAPACITY);
this.buf = Arrays.copyOfRange(this.buf, 0, WIRE_CAPACITY);
this.count = WIRE_CAPACITY;
} else {
this.waiting = new byte[0];
}
onWire += this.count;
super.flush();
if (this.waiting.length > 0) {
System.arraycopy(this.waiting, 0, this.buf, 0, Math.min(this.waiting.length, WIRE_CAPACITY));
this.count = Math.min(this.waiting.length, WIRE_CAPACITY);
}
}
}
ただし、これは正しく機能しません。WIRE_CAPACITY
次のテストケースで示されているように、バッファーにバイトよりも多くのバイトが含まれている場合、バイトは失われます。
@Test
public void testStream() throws IOException {
final ArduinoBufferedOutputStream stream = new ArduinoDisplayOutputStream.ArduinoBufferedOutputStream(System.out);
stream.write("This is a very, very long string, which must be made even longer to demonstrate the problem".getBytes());
stream.flush();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
stream.ping();
}
次の文字列が出力されます: This is a very, very long string, which must be ma
、明らかに文字列全体を出力したいのですが。
ここで私が間違っていることを誰かが見ることができますか? またはさらに良いことに、私が望むことを行う既存のライブラリを知っている人はいますか?