我有一個簡單的測試應用程序,它連接到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,它可以被捕獲以關閉該通道。
java.io阻塞API。考慮使用非阻塞的java.nio – ponomandr 2014-09-06 16:07:14
你沒有做錯任何事情,這可能是一個實現錯誤。 – 2014-09-06 16:10:48
//用數據做東西 - 你在那裏做什麼?確保該代碼中的某個位置沒有關閉該流。 – BatScream 2014-09-06 16:35:49