简体   繁体   English

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

[英]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.

相关问题 我是否需要在Java中关闭InputStream? - Do I need to close an InputStream in Java? 关闭Reader后是否需要关闭InputStream? - Do I need to close InputStream after I close the Reader 我是否需要处理或忽略OutputStream close()函数触发的IOException? - Do i need to handle or ignore the IOException fired by OutputStream close() function? 我可以关闭servlet中的包装输入流或输出流类吗? - Can I close wrapper inputstream or outputstream class in servlet? 在Java中,当我调用OutputStream.close()时,我是否总是需要先调用OutputStream.flush()? - In Java, when I call OutputStream.close() do I always need to call OutputStream.flush() before? 我是否需要在每个新输入流上调用close()? - do i need call close() on every new inputstream? 即使 InputStream 应该保持打开状态,我是否需要关闭 InputStreamReader? - Do I need to close InputStreamReader even if InputStream should remain open? 使用 getResponseCode (HttpUrlConnection) 后是否需要关闭 inputStream - Do I need close inputStream after using getResponseCode (HttpUrlConnection) 为什么我只能先关闭socket的输出流再关闭输入流? - Why I can only close socket's outputStream first and then close inputstream? 如果我关闭ObjectOuputStream,那么是否不需要关闭FileOutputStream? - If I close ObjectOuputStream, then do not need to close FileOutputStream?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM