【问题标题】:Java available bytes for BufferedInputStream isn't workingBufferedInputStream 的 Java 可用字节不起作用
【发布时间】:2014-09-06 16:04:04
【问题描述】:

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

我做错了吗?如果我注释掉 available() 调用,除了它在 read() 上阻塞大约每 50 次运行的问题之外,它可以完美地工作。我还尝试通过 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 在 cmets 中指出的那样,这是系统故障的指示性行为。我设法通过将读取重构为 AsynchronousFileChannel 对象来使其全部工作,该对象从其读取调用返回一个 Future 对象。可以通过 get() 方法中的超时从 Future 获取数据。然后会抛出一个 TimeoutException ,可以捕获该异常以关闭通道。

【问题讨论】:

  • java.io 正在阻塞 API。考虑改用 java.nio,它是非阻塞的
  • 你没有做错什么,这可能是一个实现错误。
  • // 用数据做事——你在做什么?确保该流未在该代码中的某处关闭。
  • @ponomandr java.nio 正在阻止文件。 NIO2 是非阻塞的,但实际上它只是阻塞了一个后台线程。
  • 我假设您访问的设备不支持此操作。您似乎不需要此操作,因此我会编写您的读取循环以不使用它。

标签: java usb bufferedreader bufferedinputstream


【解决方案1】:

读取我尝试的不同方法的编辑,但我设法通过将读取重构为 AsynchronousFileChannel 对象来使其全部工作,该对象从其读取调用返回一个 Future 对象。可以通过 get() 方法中的超时从 Future 获取数据。然后这会引发一个 TimeoutException,可以捕获该异常以关闭通道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多