如何知道 BufferedReader Stream 是不是关闭
Posted
技术标签:
【中文标题】如何知道 BufferedReader Stream 是不是关闭【英文标题】:How to know if a BufferedReader Stream is closed如何知道 BufferedReader Stream 是否关闭 【发布时间】:2010-11-02 03:28:27 【问题描述】:我在 Java 中有两个线程。
第一个线程正在关闭缓冲读取器 (br.close()
)
当第二个线程对同一个阅读器进行读取时,我得到一个IOException (Stream Closed)
即使我使用br.ready()
,我也会收到此异常
有没有办法知道流是否已经关闭?
【问题讨论】:
只是出于好奇,为什么多个线程使用同一个BufferedReader? 长篇大论先生......试图让一些遗留代码工作...... 请注意,要非常小心地检查哪个对象被用作 Readers 的监视器。 【参考方案1】:我认为没有任何方法可以直接调用来判断流是否已关闭。
如果你真的需要让两个线程共享这个阅读器,你最好的选择可能是让一个线程回调另一个线程,或者设置一个标志来通知它流已经关闭,这样另一个线程就不知道了尝试从中读取。
【讨论】:
对我来说似乎也是如此。我检查了 JDK 中的 BufferedReader.java。有一个 ensureOpen 私有方法检查流关闭并抛出 Stream Closed 异常。它正在检查内部读取器(用于初始化 BufferedReader 的读取器)是否为空。这是外面无法访问的。【参考方案2】:如果您已经开始了读取操作,那么您将通过 IOException 通知流已关闭。即使您之前调用过 br.ready(),当您的代码在 read 方法处被阻塞时也会发生异常。
没有办法避免这种情况。相反,您应该期望读取操作会引发异常并准备好适当地处理它。
【讨论】:
【参考方案3】:确实,查看 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");
【讨论】:
小心 - 如果类的内部发生变化,这可能会很慢并且可能会中断。我建议使用你自己的“标志”来保护缓冲区。 因为 Java 1.5 的反射不像以前那么慢了。【参考方案4】:ready()
方法在关闭时会抛出异常。但是即使你添加了一个关闭的检查方法,只要在调用之间释放了锁(它是针对BufferedReader
),阅读器可能在你阅读它的时候就被关闭了。
我看到三个选项:
-
使用 try/catch 块包装您的读取调用以处理已关闭的案例。
创建一个扩展
close()
的BufferedReader
的子类,以设置您自己的变量
可用于检查阅读器是否关闭。这也需要覆盖很多
如果您希望它在抛出IOException
之外执行某些操作,则可以使用封闭式阅读器执行您想要的任何行为的方法。
添加自己的锁并使用它来关闭阅读器(一个线程)和
检查缓冲区是否已准备好并从中读取。您可以直接为检查设置一个变量,也可以将 ready()
和 read()
调用分组到同一个同步块中。
【讨论】:
【参考方案5】:另一种方法是在您自己的类中扩展 BufferedReader,覆盖 close() 方法以指示它是否已关闭。
【讨论】:
这就是凯西在 2 中所说的 :)【参考方案6】:如果只有从 BufferedReader 读取并关闭它的东西是您的线程,我只会制作同步部分并在关闭 Reader 时设置一些平面。所以在每个线程中你应该:
-
打开同步部分。
检查流是否尚未关闭(检查标志)。
从流中读取。
关闭直播。
设置标志。
结束同步部分。
请小心并避免任何可能挂在同步部分的内容。基本上只放必要的,只读取数据,稍后处理。
【讨论】:
以上是关于如何知道 BufferedReader Stream 是不是关闭的主要内容,如果未能解决你的问题,请参考以下文章