У меня есть простое тестовое приложение, которое подключается к USB-устройству (в виде локального файла), передает стартовый символ передачи, а затем считывает ввод с устройства. Все это работает нормально, но редко он блокируется при вызове read(). Чтобы предотвратить это, я попытался проверить, есть ли хотя бы 1 доступный байт, прежде чем продолжить операцию read(). Однако, когда я запускаю это, я получаю IOException из вызова available().Доступные байты Java для BufferedInputStream не работают
Мой код:
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 запусков. Я также попытался реализовать читателя как BufferedReader над InputStreamReader (поскольку данные ASCII) и использовать метод ready() BufferedReader, но всегда возвращает false.
EDIT: Я ищу альтернативы проверке наличия данных перед чтением, большинство из которых связано с обработкой блокирующего вызова read(). У меня есть внешний поток, проверяющий тайм-аут, но если есть тайм-аут, попытка остановить поток с помощью thread.interrupt() все равно не прервет вызов блокировки read(). Точно так же закрытие InputStream из внешнего потока не работает, так как вызов по-прежнему заблокирован. Я также попробовал решение здесь https://stackoverflow.com/a/9832633/1020006, но executor.shutdownNow() - это просто оболочка для Thread.interrupt() и поэтому имеет ту же проблему. Я хочу избежать использования Thread.stop(), поскольку он устарел.
Единственный другой выбор, который я вижу, это переписать чтение с помощью FileChannel, которые асинхронно прерываются.
EDIT 2: Я попытался использовать Thread.stop(), но это также не сработало, как отметил Питер Лоури в комментариях, это показательное поведение системной ошибки. Мне удалось заставить все это работать, рефакторинг чтения в объект AsynchronousFileChannel, который возвращает объект Future из его прочитанного вызова. Данные можно получить из Будущего с тайм-аутом в методе get(). Затем это генерирует исключение TimeoutException, которое можно поймать, чтобы закрыть канал.
java.io блокирует API. Вместо этого используйте java.nio, который не блокирует – ponomandr
. Вы ничего не делаете неправильно, это может быть ошибка реализации. –
// Делайте материал с данными - что вы там делаете? Убедитесь, что поток не закрыт где-то в этом коде. – BatScream