我有一个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();
有时我想关闭套接字。我必须关闭溪流吗?
问题是每个close()
都可能抛出异常,我必须抓住它们,
并且代码变得臃肿。
BluetoothSocket
没有记录这种行为(或者我找不到它)。
所以:
如果我关闭蓝牙套接字,是否必须关闭其流?
(那么Socket
s呢?它们有什么不同吗?BluetoothSocket
不会继承Socket
。)
答案 0 :(得分:1)
我最近一直在研究Android蓝牙。我检查了消息来源。似乎你不需要关闭你的溪流。
实际上,您在BluetoothSocket构造函数中分别流式处理BluetoothInputStream和BluetoothOutputStream类型的对象:
mInputStream = new BluetoothInputStream(this);
mOutputStream = new BluetoothOutputStream(this);
这些是您致电时返回的信息流:
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
但是当你在这些流上调用.close()时,你会调用:
public void close() throws IOException {
mSocket.close();
}
所以你只能再次关闭BluetoothSocket。
总之,您无需关闭这些流。
对于你的第二个问题,Socket和BluetoothSocket唯一的共同点是它们实现了Closable:它们将有一个.close()方法。这并不意味着他们做同样的事情
以下是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();
}
}
答案 1 :(得分:1)
您应该先关闭流。只有在套接字上调用close()
通常才能解决,但如果紧接着打开一个新连接(读取:单元测试),你就会遇到问题。
答案 2 :(得分:0)
有时我想关闭套接字。我必须关闭 流?问题是每个close()可能抛出异常,I 必须抓住它们,代码变得臃肿。
如果文档中没有提及任何内容,我认为你应该关闭它。如果您的问题只是例外,您可以使用实用方法,例如
public void closeStream(Closeable stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}