2009-06-11 6 views
12

У меня есть два потока в Java.Как узнать, закрыт ли поток BufferedReader

Первого потока закрытие BufferedReader (br.close())

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

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

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

+4

Просто из любопытства, почему несколько потоков используют тот же BufferedReader? –

+0

long story sir..trying для получения устаревшего кода для работы ... – 2009-06-11 14:00:25

+0

Просто обратите внимание, чтобы быть очень осторожным, чтобы точно проверить, какой объект используется в качестве монитора с помощью Readers. –

ответ

1

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

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

+0

Мне тоже показалось, что это так. Я проверил BufferedReader.java в JDK. Существует закрытый метод secureOpen, который проверяет закрытие потока и генерирует исключение Stream Closed. Он проверяет, является ли внутренний Reader (тот, который используется для инициализации BufferedReader) равен нулю. Это недоступно снаружи. – 2009-06-11 14:03:55

1

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

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

0

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

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"); 
} 
+0

Это, похоже, работает автономно. Позвольте мне попробовать это на сервере. – 2009-06-11 15:18:24

+1

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

+0

Поскольку отражение Java 1.5 не так медленно, как раньше. –

6

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

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

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

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

+1

Вот что сказала Кэти в 2: –

0

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

  1. Открыть синхронизированный раздел.
  2. Проверьте, не закончился ли поток (отметьте флаг).
  3. Читайте с потока.
  4. Закрыть поток.
  5. Установите флаг.
  6. End synchronized section.

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

Смежные вопросы