Подтвердить что ты не робот

Как узнать, закрыт ли поток BufferedReader

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

Первая нить закрывает буферизованный читатель (br.close())

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

В самом деле, глядя на secureOpen(), он проверяет, не является ли объект 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");
 }

Ответ 6

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

  • Открыть синхронизированный раздел.
  • Проверить, что поток уже не закрыт (отметьте флаг).
  • Чтение из потока.
  • Закрыть поток.
  • Установите флаг.
  • Завершить синхронизированный раздел.

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