Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果我关闭BluetoothSocket,是否需要关闭InputStream/OutputStream?_Java_Android_Bluetooth - Fatal编程技术网

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

Java 如果我关闭BluetoothSocket,是否需要关闭InputStream/OutputStream?,java,android,bluetooth,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.getOutp

我有一个
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

在某个时刻,我想关上插座。我必须关上窗户吗 溪流?问题是每个close()都可能抛出一个异常 必须抓住它们,代码就会变得臃肿

如果文档中没有提到任何内容,我认为您应该关闭它。如果您的问题只是一个例外,那么您可以使用一个实用方法,例如

public void closeStream(Closeable stream) {
   if (stream == null) {
       return;
   }

   try {
      stream.close();
   } catch (IOException e) {
       e.printStackTrace();
   }
}

我最近一直在研究Android蓝牙。我查了资料来源。而且似乎您不需要关闭您的流。

实际上,在BluetoothSocket构造函数中,流分别是BluetoothInputStream和BluetoothOutputStream类型的对象:

mInputStream = new BluetoothInputStream(this);
mOutputStream = new BluetoothOutputStream(this);
这些是您调用时返回的流:

InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
public void close() throws IOException {
    mSocket.close();
}
但当您对这些流调用.close()时,您会调用:

InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
public void close() throws IOException {
    mSocket.close();
}
所以你只需再次关闭蓝牙插座

总之,您不需要关闭这些流。

对于第二个问题,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();
}
/*包*/最终类BluetoothOutputStream扩展了OutputStream{
私人蓝牙插座mSocket;
/*包*/BluetoothOutputStream(BluetoothSocket s){
mSocket=s;
}
/**
*关闭此输出流及其关联的套接字。
*/
public void close()引发IOException{
mSocket.close();
}
/**
*将单个字节写入此流。仅将
*整数{@code oneByte}被写入流中。
*
*@param单字节
*要写入的字节。
*@抛出异常
*如果写入此流时发生错误。
*@自Android 1.0以来
*/
public void write(int-oneByte)引发IOException{
字节b[]=新字节[1];
b[0]=(字节)一个字节;
mSocket.write(b,0,1);
}
/**
*从字节数组{@code buffer}开始写入{@code count}字节
*在该流的{@code offset}位置。
*
*@param b
*要写入的缓冲区。
*@param偏移量
*{@code buffer}中从何处获取字节的起始位置。
*@param计数
*从{@code buffer}写入此缓存的字节数
*小溪。
*@抛出异常
*如果写入此流时发生错误。
*@throws IndexOutOfBoundsException
*如果{@code offset<0}或{@code count<0},或如果
*{@code offset+count}大于
*{@code buffer}。
*@自Android 1.0以来
*/
公共无效写入(字节[]b,整数偏移量,整数计数)引发IOException{
如果(b==null){
抛出新的NullPointerException(“缓冲区为null”);
}
if((偏移量|计数)<0 |计数>b.长度-偏移量){
抛出新的IndexOutOfBoundsException(“无效偏移量或长度”);
}
mSocket.write(b,偏移量,计数);
}
/**
*等待发送队列中的数据清空。轮询版本
*用于flush实现。使用它确保以后写入数据
*包装在新的RFCOMM框架中。
*@抛出异常
*如果发生i/o错误。
*@自Android 4.2.3以来
*/
public void flush()引发IOException{
mSocket.flush();
}

}

您应该先关闭流。通常只能在套接字上调用
close()
,但是如果紧接着打开了一个新的连接(读:单元测试),就会出现问题

您还可以使用
varargs
Closeable
并在其上进行循环,
BluetoothOutputStream.close()
被记录以关闭此输出流及其关联的套接字,但
BluetoothOutputStream
本身未被记录(包可见).我进行了编辑,以便您可以查看BluetoothOutputStream的完整代码。close()不关闭outputstream,它只关闭BluetoothSocket。但可能它被记录为关闭输出流,因为当BluetoothSocket关闭时,它会关闭实际的输出流(您无权访问的流)。