14

我在 Java 中有两个线程。

第一个线程正在关闭缓冲读取器(br.close()

当第二个线程在同一个阅读器上阅读时,我得到一个IOException (Stream Closed)

即使我使用,我也会收到此异常br.ready()

有没有办法知道流是否已经关闭?

4

6 回答 6

8

如果关闭,该方法ready()将抛出异常。但是即使你添加了一个关闭的检查方法,只要在调用之间释放了锁(它是 for BufferedReader),阅读器可能会在你阅读它的时候被关闭。

我看到三个选项:

  1. 用 try/catch 块包装您的读取调用以处理已关闭的案例。
  2. 创建一个BufferedReader扩展的子类close()以设置您自己的变量,该变量可用于检查阅读器是否已关闭。如果您希望它在抛出IOException.
  3. 添加您自己的锁并使用它来关闭阅读器(一个线程)并检查缓冲区是否已准备好并从中读取。您可以直接为检查设置一个变量,也可以将ready()andread()调用分组到同一个同步块中。
于 2009-06-11T15:23:30.553 回答
1

另一种方法是在您自己的类中扩展 BufferedReader,覆盖 close() 方法以指示它是否已关闭。

于 2009-06-11T15:26:30.953 回答
1

我认为没有任何方法可以直接调用来判断流是否关闭。

如果你真的需要两个线程共享这个阅读器,你最好的选择可能是让一个线程回调另一个线程或设置一个标志来通知它流已经关闭,这样另一个线程就知道不要尝试从中读取。

于 2009-06-11T14:01:07.833 回答
1

如果您已经开始了读取操作,那么您将通过 IOException 通知流已关闭。即使您之前调用过 br.ready(),当您的代码在 read 方法处被阻塞时,也会发生异常。

没有办法避免这种情况。相反,您应该期望读取操作会引发异常并准备好适当地处理它。

于 2009-06-11T14:01:49.423 回答
0

如果只有从 BufferedReader 读取并关闭它的东西是您的线程,我只会制作同步部分并在关闭 Reader 时设置一些平面。所以在每个线程中你应该:

  1. 打开同步部分。
  2. 检查流是否尚未关闭(检查标志)。
  3. 从流中读取。
  4. 关闭流。
  5. 设置标志。
  6. 结束同步部分。

请小心并避免任何可能挂在同步部分的东西。基本上只放必要的东西,只读取数据,稍后再处理。

于 2009-06-11T20:39:02.683 回答
0

实际上,查看 ensureOpen() 它会检查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");
 }
于 2009-06-11T14:36:27.687 回答