[英]do I need to close InputStream/OutputStream if I close BluetoothSocket?
I have a BluetoothSocket
and two streams. 我有一个
BluetoothSocket
和两个流。
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
BluetoothSocket s = (BluetoothSocket) m.invoke(device, 1);
s.connect();
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
At some moment I want to close the socket. 有时我想关闭插座。 Do I have to close the streams?
我必须关闭溪流吗? The problem is that each
close()
may throw an exception, I have to catch them, and the code becomes bloated. 问题是每个
close()
可能引发异常,我必须抓住它们,并且代码变得肿。
IIRC in some similar case it was enough to close the main object (which would be the socket in this case), and other objects were closed automatically. 在某些类似情况下,IIRC足以关闭主要对象(在这种情况下为插座),而其他对象则自动关闭。 But this behavior is not documented for
BluetoothSocket
(or I could not find it). 但是没有针对
BluetoothSocket
记录此行为(或者我找不到它)。
So: 所以:
If I close a bluetooth socket, do I have to close its streams? 如果我关闭了蓝牙插座,是否必须关闭其插口?
(And what about Socket
s? Are they different? BluetoothSocket
does not inherit from Socket
.) (那
Socket
是什么?它们有什么不同? BluetoothSocket
不继承自Socket
。)
I have been working on Android Bluetooth recently. 我最近一直在研究Android蓝牙。 I checked the sources.
我检查了来源。 And it seems that you don't need to close your streams.
看来您不需要关闭流。
Indeed, you stream are respectively objects of type BluetoothInputStream and BluetoothOutputStream in the BluetoothSocket constructor: 实际上,您的流分别是BluetoothSocket构造函数中的BluetoothInputStream和BluetoothOutputStream类型的对象:
mInputStream = new BluetoothInputStream(this);
mOutputStream = new BluetoothOutputStream(this);
Those are streams returned when you call: 这些是您致电时返回的流:
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
But when you call .close() on these streams, you call: 但是,当您在这些流上调用.close()时,您将调用:
public void close() throws IOException {
mSocket.close();
}
So you only close the BluetoothSocket again. 因此,您只需再次关闭BluetoothSocket。
In conclusion, you don't need to close those streams. 总之,您不需要关闭这些流。
For your second question, the only thing that Socket and BluetoothSocket have in common is that they implement Closable: they will have a .close() method. 对于第二个问题,Socket和BluetoothSocket唯一的共同点是它们实现了Closable:它们将具有.close()方法。 It does not mean they do the same
这并不意味着他们会这样做
Here is the complete code for BluetoothOutputStream: 这是BluetoothOutputStream的完整代码:
/*package*/ final class BluetoothOutputStream extends OutputStream {
private BluetoothSocket mSocket;
/*package*/ BluetoothOutputStream(BluetoothSocket s) {
mSocket = s;
}
/**
* Close this output stream and the socket associated with it.
*/
public void close() throws IOException {
mSocket.close();
}
/**
* Writes a single byte to this stream. Only the least significant byte of
* the integer {@code oneByte} is written to the stream.
*
* @param oneByte
* the byte to be written.
* @throws IOException
* if an error occurs while writing to this stream.
* @since Android 1.0
*/
public void write(int oneByte) throws IOException {
byte b[] = new byte[1];
b[0] = (byte)oneByte;
mSocket.write(b, 0, 1);
}
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting
* at position {@code offset} to this stream.
*
* @param b
* the buffer to be written.
* @param offset
* the start position in {@code buffer} from where to get bytes.
* @param count
* the number of bytes from {@code buffer} to write to this
* stream.
* @throws IOException
* if an error occurs while writing to this stream.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if
* {@code offset + count} is bigger than the length of
* {@code buffer}.
* @since Android 1.0
*/
public void write(byte[] b, int offset, int count) throws IOException {
if (b == null) {
throw new NullPointerException("buffer is null");
}
if ((offset | count) < 0 || count > b.length - offset) {
throw new IndexOutOfBoundsException("invalid offset or length");
}
mSocket.write(b, offset, count);
}
/**
* Wait until the data in sending queue is emptied. A polling version
* for flush implementation. Use it to ensure the writing data afterwards will
* be packed in the new RFCOMM frame.
* @throws IOException
* if an i/o error occurs.
* @since Android 4.2.3
*/
public void flush() throws IOException {
mSocket.flush();
}
} }
You should close the streams first. 您应该先关闭流。 Only calling
close()
on the socket will usually work out, but if a new connection is opened immediately following (read: unit testing), you'll have problems. 通常只有在套接字上调用
close()
才能解决问题,但是如果紧接在后打开一个新连接(阅读:单元测试),则会遇到问题。
At some moment I want to close the socket.
有时我想关闭插座。 Do I have to close the streams?
我必须关闭溪流吗? The problem is that each close() may throw an exception, I have to catch them, and the code becomes bloated.
问题是每个close()都可能引发异常,我必须抓住它们,并且代码变得肿。
If the documentation does not mention nothing about it, I think you should close it. 如果文档中没有提及任何内容,我认为您应该将其关闭。 If your problem is just the exception, you can have an utility method, such
如果您的问题只是例外,则可以使用一种实用程序方法,例如
public void closeStream(Closeable stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.