我有一个简单的测试应用程序,它连接到USB设备(作为本地文件),传输开始传输字符,然后从设备读取输入。这一切工作正常,但很少会阻止read()调用。为了防止这种情况,我试图在继续read()操作之前检查是否至少有1个可用字节。但是,当我运行这个时,我从available()调用中得到一个IOException。BufferedInputStream的Java可用字节不工作
我的代码是:
public static void testRecord() {
// Records data for a second
String portName = "\\\\.\\<DEVICE_FILE>";
FileWriter out = null;
byte singleByte;
long startTime = System.currentTimeMillis();
try {
out = new FileWriter(portName);
out.write('c'); // start data transmission
out.write(0x0d); // carriage return required
out.flush();
if (out != null)
out.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(portName), 512);
System.out.println("Connected to device");
while(System.currentTimeMillis() < startTime+1000) {
avail = bis.available();
if (!(avail > 0)) {
System.out.println("Available: " + avail);
continue;
}
singleByte = (byte) bis.read();
// Do stuff with data
}
if (bis != null)
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("ERROR");
}
}
的错误跟踪:
Connected to device
java.io.IOException
at java.io.FileInputStream.available(Native Method)
at java.io.BufferedInputStream.available(Unknown Source)
at test.Test.testRecord(Test.java:58)
at test.Test.main(Test.java:135)
ERROR
我做错什么了吗?如果我注释掉可用的()调用,那么除了它每隔50次运行一次大约阻塞read()的问题之外,它完全可以工作。我也尝试通过InputStreamReader(作为数据是ASCII)并使用BufferedReader的ready()方法实现读取器作为BufferedReader,但始终返回false。
编辑:我正在寻找替代方法来检查在读取之前是否有数据可用,其中大部分涉及处理阻塞的read()调用。我有一个外部线程检查超时,但如果有超时,试图用thread.interrupt()停止线程仍然不会中断阻塞read()调用。同样,从外线关闭InputStream不起作用,因为呼叫仍然被阻止。我也试过这里的解决方案https://stackoverflow.com/a/9832633/1020006但是executor.shutdownNow()只是Thread.interrupt()的一个包装,所以也有同样的问题。我想避免使用Thread.stop(),因为它已被弃用。
我能看到的唯一的另一种选择是使用FileChannel重写读取,它们是异步中断的。
编辑2:我尝试过使用Thread.stop(),但这也不起作用,正如Peter Lawrey在评论中指出的那样,这是系统故障的指示性行为。我设法通过将读取重构为一个AsynchronousFileChannel对象来完成所有工作,AsynchronousFileChannel对象从其读取调用中返回一个Future对象。可以通过get()方法中的超时从Future中获取数据。然后这会引发一个TimeoutException,它可以被捕获以关闭该通道。
java.io阻塞API。考虑使用非阻塞的java.nio – ponomandr 2014-09-06 16:07:14
你没有做错任何事情,这可能是一个实现错误。 – 2014-09-06 16:10:48
//用数据做东西 - 你在那里做什么?确保该代码中的某个位置没有关闭该流。 – BatScream 2014-09-06 16:35:49