BufferedInputStream的Java可用字节数为';行不通
我有一个简单的测试应用程序,它连接到USB设备(作为本地文件),传输开始传输字符,然后从设备读取输入。这一切都很好,但很少会阻塞read()调用。为了防止出现这种情况,我尝试在继续执行read()操作之前检查是否至少有1个可用字节。然而,当我运行这个函数时,我从available()调用中得到了一个IOException 我的代码是:BufferedInputStream的Java可用字节数为';行不通,java,usb,bufferedreader,bufferedinputstream,Java,Usb,Bufferedreader,Bufferedinputstream,我有一个简单的测试应用程序,它连接到USB设备(作为本地文件),传输开始传输字符,然后从设备读取输入。这一切都很好,但很少会阻塞read()调用。为了防止出现这种情况,我尝试在继续执行read()操作之前检查是否至少有1个可用字节。然而,当我运行这个函数时,我从available()调用中得到了一个IOException 我的代码是: public static void testRecord() { // Records data for a second String por
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");
}
}
我做错什么了吗?如果我注释掉available()调用,那么除了它大约每隔50次阻塞read()一次的问题之外,它工作得非常好。我还尝试将读取器实现为InputStreamReader上的BufferedReader(因为数据是ASCII),并使用BufferedReader的ready()方法,但总是返回false
编辑:我正在寻找在读取之前检查是否有可用数据的替代方法,其中大部分涉及处理阻塞read()调用。我有一个外部线程检查超时,但是如果有超时,尝试用thread.interrupt()停止线程仍然不会中断blocking read()调用。同样,从外部线程关闭InputStream也不起作用,因为调用仍然被阻塞。我在这里也尝试过这个解决方案,但executor.shutdownNow()只是Thread.interrupt()的包装器,因此也有同样的问题。我希望避免使用Thread.stop(),因为它已被弃用
我能看到的唯一其他选择是使用一个异步可中断的FileChannel重写读取
编辑2:我尝试使用Thread.stop(),但这也不起作用,正如Peter Lawrey在评论中指出的,这表明系统出现故障。通过将读取重构为AsynchronousFileChannel对象,该对象从其读取调用返回一个将来的对象,我成功地实现了这一切。可以通过get()方法中的超时从未来获取数据。然后抛出一个TimeoutException,可以捕获它来关闭通道。读取我尝试过的不同方法的编辑,但我通过将读取重构为AsynchronousFileChannel对象,该对象从其读取调用返回一个未来的对象,从而成功地完成了所有工作。可以通过get()方法中的超时从未来获取数据。然后抛出一个TimeoutException,可以捕获该异常以关闭通道。java.io正在阻塞API。考虑使用JavaNIO代替,这是不阻塞你没有做错任何事情,这可能是一个实现错误。/ /用数据做什么-你在那里做什么?确保流在代码中的某个地方没有关闭。@ponomandr java.nio正在阻止文件。NIO2是非阻塞的,但实际上它只是阻塞了一个后台线程。您似乎不需要此操作,因此我将编写您的读取循环以不使用它。
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