BufferedInputStream的Java可用字节不起作用

时间:2014-09-06 16:04:04

标签: java usb bufferedreader bufferedinputstream

我有一个简单的测试应用程序,它连接到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,可以捕获它以关闭通道。

1 个答案:

答案 0 :(得分:0)

阅读我尝试的不同方法的编辑,但我设法通过将读取重构为AsynchronousFileChannel对象来完成所有工作,该对象从其read调用返回Future对象。可以通过get()方法中的超时从Future获取数据。然后抛出一个TimeoutException,可以捕获它以关闭通道。