BufferedInputStream的Java可用字节数为';行不通

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

我有一个简单的测试应用程序,它连接到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");
    }

}
我做错什么了吗?如果我注释掉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