我有一个简单的测试应用程序,它连接到USB设备(作为本地文件),传输开始传输字符,然后从设备读取输入。这一切都很好,但很少会阻止read()调用。为了防止这种情况,我尝试在继续read()操作之前检查是否至少有1个可用字节。但是当我运行它时,我从available()调用中得到一个IOException。
我的代码是:
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上的BufferedReader(因为数据是ASCII)并使用BufferedReader的ready()方法但总是返回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对象来完成所有工作,该对象从其read调用返回Future对象。可以通过get()方法中的超时从Future获取数据。然后抛出一个TimeoutException,可以捕获它以关闭通道。
答案 0 :(得分:0)
阅读我尝试的不同方法的编辑,但我设法通过将读取重构为AsynchronousFileChannel对象来完成所有工作,该对象从其read调用返回Future对象。可以通过get()方法中的超时从Future获取数据。然后抛出一个TimeoutException,可以捕获它以关闭通道。