Java 如何知道 BufferedReader Stream 是否已关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/981196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:50:30  来源:igfitidea点击:

How to know if a BufferedReader Stream is closed

javaiobufferedreader

提问by

I have two threads in Java.

我在 Java 中有两个线程。

First thread is closing a bufferedreader (br.close())

第一个线程正在关闭一个 bufferedreader ( br.close())

When the second thread does a read on the same reader I get an IOException (Stream Closed)

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

I get this exception even if I use br.ready()

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

Is there a way to know if the stream is already closed?

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

回答by Eric Petroelje

I don't think there's any method you can call directly to tell if a stream is closed.

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

If you really need to have two threads sharing this reader, your best option might be to have the one thread call back to the other thread or set a flag to notify it that the stream has been closed so the other thread knows not to try to read from it.

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

回答by kgiannakakis

If you have already started a read operation, then you will notified with an IOException that a stream is closed. Even if you have called br.ready() before, the exception is happening when your code is blocked at the read method.

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

There is no way to avoid this. On the contrary, you should expect a read operation to throw an exception and be prepared to handle it appropriately.

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

回答by Alexandru Luchian

Indeed, looking at ensureOpen() it checks if the inobject is not null. Since it is private we can't access it from outside. But if you really need it, you can use reflection.

实际上,查看 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");
 }

回答by Kathy Van Stone

The method ready()will throw an exception if closed. But even if you added a closed check method, so long as the lock is released between calls (which it is for BufferedReader), the reader might be closed by the time you read it.

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

I see three options:

我看到三个选项:

  1. Wrap your read call with a try/catch block to handle the closed case.
  2. Create a subclass of BufferedReaderthat extends close()to set your own variable that can be used to check to see if the reader is closed. This also requires overriding a lot of methods to do whatever the behavior you want with a closed reader if you want it do something beside throw the IOException.
  3. Add a lock of your own and use it to both close the reader (one thread) and check that the buffer is ready and read from it. You can either set a variable directly for the check or just group the ready()and read()calls into the same synchronized block.
  1. 用 try/catch 块包装你的 read 调用来处理关闭的情况。
  2. 创建一个BufferedReader扩展的子类close()来设置您自己的变量,该变量可用于检查阅读器是否已关闭。这也需要覆盖很多方法,如果你想让它做一些除了抛出IOException.
  3. 添加您自己的锁并使用它来关闭读取器(一个线程)并检查缓冲区是否准备好并从中读取。您可以直接为检查设置一个变量,也可以将ready()read()调用分组到同一个同步块中。

回答by Yoni Roit

Another way would be to extend a BufferedReader in your own class, overriding close() method to indicate if it was closed.

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

回答by amorfis

If only things that read from BufferedReader and close it are your threads, I would just make synchronized section and set some flat when closing the Reader. So in each thread you should:

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

  1. Open synchronized section.
  2. Check if stream isn't closed already (check the flag).
  3. Read from stream.
  4. Close stream.
  5. Set the flag.
  6. End synchronized section.
  1. 打开同步部分。
  2. 检查流是否尚未关闭(检查标志)。
  3. 从流中读取。
  4. 关闭流。
  5. 立旗。
  6. 结束同步部分。

Just be careful and avoid anything that could hang in synchronized section. Basically put there only what is necessary, only read data, process it later.

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