问题描述
我目前正在编写一个使用 TCP 套接字与服务器通信的程序.其中一部分需要通过多种方法来回发送信息.但是,我不想为每个请求打开一个新的套接字连接,但我不能保证请求的数量或顺序.为了解决这个问题,我只保留了一个可以重复使用的套接字实例.
I'm currently writing a program that communicates with a server using TCP sockets. Part of that requires sending information back and forth through several methods. However, I do not want to open up a new socket connection for each request, but I can't guarantee the number or the order of the requests. In order to handle this, I simply keep one socket instance that gets reused a lot.
然而,为了读取数据,我使用了 BufferedReader
包装类.因为我重用了同一个套接字,所以我不能在阅读器上调用 close()
,否则我也会关闭套接字流.
However, in order to read the data I use BufferedReader
wrapper classes. Because I reuse the same socket, I can't call close()
on the reader, or I'll close the socket stream as well.
如果我不想关闭底层流,是否需要在 BufferedReader 上调用 close()
?不这样做会导致内存泄漏吗?如果我确实需要调用 close()
如何在不关闭套接字流的情况下返回内存?
Do I need to call close()
on the BufferedReader if I don't want to close the underlying stream? Will I cause a memory leak by not doing this? If I do need to call close()
how can I return the memory without closing the socket's stream?
注意:我将在程序终止时关闭底层流,这个问题与此无关.
Note: I will close the underlying stream at program termination, this question isn't about that.
推荐答案
不要关闭 BufferedReade
.更重要的,不要丢弃BufferedReader
;相反,传递它而不是 SocketInputStream
.
Don't close the BufferedReade
. More important, don't discard the BufferedReader
; instead, pass it around rather than the SocketInputStream
.
BufferedReader
,顾名思义,有一个内部缓冲区.当您读取它时,它会尝试从底层 Reader
填充该缓冲区.这意味着,如果你丢弃它,那些字节就会消失.
A BufferedReader
, as its name implies, has an internal buffer. When you read from it, it tries to fill that buffer from the underlying Reader
. Which means that, if you discard it, those bytes are gone.
现在是一些未经询问的建议:
And now some unasked advice:
- 您真的要使用
Reader
吗?大多数通信协议使用DataInputStream
/DataOutputStream
可以更好地实现.使用Reader
,您只能读取字符数据(对于BR
,则是字符数据行). - 您是否关注编码?在
InputStream
之上构造Reader
的正确方法是使用InputStreamReader
的两个参数变体:new InputStreamReader(in, "UTF-8")
(您可以使用 UTF-8 以外的编码,但有充分的理由). - 通常最好使用
BufferedInputStream
而不是BufferedReader
,因为从流到读取器的转换可能涉及多次读取.如果你想要readLine()
,你可以同时使用两者. - 确保在
finally
或 try-with-resources 中关闭 socket.请参阅此了解更多信息.
- Do you really want to use a
Reader
? Most communication protocols are better implemented using aDataInputStream
/DataOutputStream
. With aReader
you're limited to character data (and in the case ofBR
, lines of character data). - Are you paying attention to encoding? The correct way to construct a
Reader
on top of anInputStream
is to use the two-argument variant ofInputStreamReader
:new InputStreamReader(in, "UTF-8")
(you can use an encoding other than UTF-8, but have a good reason). - It's generally better to use a
BufferedInputStream
rather than aBufferedReader
, because the translation from stream to reader may involve multiple reads. If you wantreadLine()
, you can always use both. - Be sure to close the socket in either a
finally
or try-with-resources. See this for more info.
这篇关于关闭 BufferedReader 而不关闭包装流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!