使用read和IOUtils.copy从InputStream读取数据的区别

5

我正在尝试使用两种方法通过蓝牙套接字从InputStream读取数据。

第一种方法是:

InputStream inputStream = bluetoothSocket.getInputStream();
byte[] buffer = new byte[1024];
inputStream.read(buffer);
String clientString = new String(buffer, "UTF-8");

这个问题在于,现在的clientString中会包含原始消息以及"0"直到缓冲区被填满(如果我使用前几个字节作为指示器,我可以知道消息的长度,但是我尽量避免这样做)。
第二种方法是(使用Apache Commons IO中的IOUtils类):
InputStream inputStream = bluetoothSocket.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
String clientString = writer.toString();

这个问题在于它停留在“复制”行,从这一点开始永远不会继续。

所以,我的问题是,这些方法之间有什么区别,为什么我得到了不同的结果?
客户端代码如下(使用C#和“32feet”):
client.Connect(BluetoothEndPoint(device.DeviceAddress, mUUID));
bluetoothStream = client.GetStream();                            
if (client.Connected == true && bluetoothStream != null)
{
    byte[] msg = System.Text.Encoding.UTF8.GetBytes(buffer + "\n");
    bluetoothStream.Write(msg, 0, msg.Length);
    bluetoothStream.Flush();
}
1个回答

3
我猜测IOUtils类来自于Apache Commons IO。它会从输入流读取数据并将其写入到输出流,直到流的末尾(从流中读取方法返回-1)。而你的第一个方法只是试图读取最大值为1024的字节,然后继续执行。

此外,inputStream.read(buffer)会返回已读取的字节数。所以在创建字符串时,你可以使用这个值:

int read = inputStream.read(buffer);    
String clientString = new String(buffer, 0, read, "UTF-8")

你还需要检查读取方法是否返回-1,表示已达到流的末尾。

但是为什么它不停止呢? - SharonKo
1
这可能取决于InputStream的实现,例如它可以返回它当前在缓冲区中持有的字节。没有必要读取完整提供的缓冲区。 - Zoran Regvart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接