2014-09-06 22 views
1

我有一个简单的测试应用程序,它连接到USB设备(作为本地文件),传输开始传输字符,然后从设备读取输入。这一切工作正常,但很少会阻止read()调用。为了防止这种情况,我试图在继续read()操作之前检查是否至少有1个可用字节。但是,当我运行这个时,我从available()调用中得到一个IOException。BufferedInputStream的Java可用字节不工作

我的代码是:

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(作为数据是ASCII)并使用BufferedReader的ready()方法实现读取器作为BufferedReader,但始终返回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对象来完成所有工作,AsynchronousFileChannel对象从其读取调用中返回一个Future对象。可以通过get()方法中的超时从Future中获取数据。然后这会引发一个TimeoutException,它可以被捕获以关闭该通道。

+0

java.io阻塞API。考虑使用非阻塞的java.nio – ponomandr 2014-09-06 16:07:14

+0

你没有做错任何事情,这可能是一个实现错误。 – 2014-09-06 16:10:48

+0

//用数据做东西 - 你在那里做什么?确保该代码中的某个位置没有关闭该流。 – BatScream 2014-09-06 16:35:49

回答

0

阅读我尝试过的不同方法的编辑,但我设法通过将读取重构为一个AsynchronousFileChannel对象,从读取调用中返回一个Future对象,从而实现了所有工作。可以通过get()方法中的超时从Future中获取数据。然后这会引发一个TimeoutException,它可以被捕获以关闭该通道。