我正在通过 USB 连接将数据从我的 Java 应用程序推送到另一端的 Arduino。
Arduino 只能在其末尾缓冲 64 字节的数据,因此我必须限制从我的 Java 应用程序的每个“gulp”中发送的字节数(多余的字节将丢失)。当 Arduino 代码准备好接收更多字节时,它会发送一个简单的 ping 线路。
所以,我扩展BufferedOutputStream
了一个类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
,而我显然希望打印整个字符串。
谁能看到我在这里做错了什么?或者更好的是,有人知道现有的图书馆可以满足我的要求吗?