如果我关闭BluetoothSocket,是否需要关闭InputStream / OutputStream?

时间:2014-09-25 08:38:44

标签: java android bluetooth

我有一个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()都可能抛出异常,我必须抓住它们, 并且代码变得臃肿。

在类似的情况下,IIRC足以关闭主要对象(在这种情况下将是套接字),并且其他对象自动关闭。但是BluetoothSocket没有记录这种行为(或者我找不到它)。

所以:

如果我关闭蓝牙套接字,是否必须关闭其流?

(那么Socket s呢?它们有什么不同吗?BluetoothSocket不会继承Socket。)

3 个答案:

答案 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();
   }
}