Как узнать, закрыт ли поток BufferedReader - PullRequest
13 голосов
/ 11 июня 2009

У меня есть два потока в Java.

Первый поток закрывает буферный ридер (br.close())

Когда второй поток выполняет чтение на том же ридере, я получаю IOException (Stream Closed)

Я получаю это исключение, даже если я использую br.ready()

Есть ли способ узнать, если поток уже закрыт?

Ответы [ 6 ]

8 голосов
/ 11 июня 2009

Метод ready() сгенерирует исключение в случае его закрытия. Но даже если вы добавили закрытый метод проверки, если между вызовами снята блокировка (что для BufferedReader), считыватель может быть закрыт к тому моменту, когда вы его прочитаете.

вижу три варианта:

  1. Оберните ваш вызов чтения блоком try / catch для обработки закрытого регистра.
  2. Создайте подкласс BufferedReader, который расширяет close(), чтобы установить собственную переменную, которая может быть использован для проверки, если читатель закрыт. Это также требует переопределения много методы, позволяющие делать то, что вам нужно, с закрытым читателем, если вы хотите, чтобы он что-то делал, кроме броска
  3. Добавьте свой собственный замок и используйте его, чтобы закрыть ридер (один поток) и проверьте, что буфер готов и прочитайте из него. Вы можете установить переменную непосредственно для проверки или просто сгруппировать вызовы ready() и read() в один и тот же синхронизированный блок.
1 голос
/ 11 июня 2009

Другим способом было бы расширить BufferedReader в вашем собственном классе, переопределив метод close (), чтобы указать, был ли он закрыт.

1 голос
/ 11 июня 2009

Если вы уже начали операцию чтения, то с IOException вы получите уведомление о том, что поток закрыт. Даже если вы уже вызывали br.ready (), исключение происходит, когда ваш код заблокирован методом read.

Нет способа избежать этого. Напротив, вы должны ожидать, что операция чтения сгенерирует исключение и будет готова обработать его соответствующим образом.

1 голос
/ 11 июня 2009

Я не думаю, что есть какой-либо метод, который можно вызвать напрямую, чтобы узнать, закрыт ли поток.

Если вам действительно нужно иметь два потока, совместно использующих этот ридер, лучшим вариантом может быть обратный вызов одного потока к другому потоку или установка флага, чтобы уведомить его о том, что поток закрыт, так что другой поток не знает пытаться читать с него.

0 голосов
/ 12 июня 2009

Если ваши вещи читают только то, что читает из BufferedReader и закрывает его, я бы просто сделал синхронизированный раздел и установил некоторую плоскость при закрытии Reader. Таким образом, в каждой теме вы должны:

  1. Открыть синхронизированный раздел.
  2. Проверьте, не закрыт ли поток (установите флажок).
  3. Чтение из потока.
  4. Закрыть поток.
  5. Установите флаг.
  6. Конец синхронизированной секции.

Просто будьте осторожны и избегайте всего, что может зависнуть в синхронизированном разделе. В основном положите туда только то, что нужно, только прочитайте данные, обработайте их позже.

0 голосов
/ 11 июня 2009

Действительно, глядя на sureOpen (), он проверяет, не является ли объект in нулевым. Поскольку это личное, мы не можем получить к нему доступ извне. Но если вам это действительно нужно, вы можете использовать отражение.

 BufferedReader myBR  = new BufferedReader(new FileReader("c:/somefile.txt"));
 myBR.close();

 Class c = myBR.getClass();
 Field in = c.getDeclaredField("in");
 in.setAccessible(true);         
 Object inReader = in.get(myBR);


 if(inReader == null){
     System.out.println("is closed");
 }
 else{
     System.out.println("is open");
 }
...