使用 read 与 IOUtils.copy 从 InputStream 读取

Sha*_*nKo 5 java sockets android bluetooth

我正在尝试使用 2 种方法来InputStream通过蓝牙套接字进行读取。

第一个是:

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

这个问题是,现在clientString有原始消息加上“0”,直到缓冲区已满(如果我将使用第一个字节作为指示符,我可以知道消息的长度,但我尽量不这样做)。

第二个是(使用IOUtils来自 的类Apache Commons IO):

InputStream inputStream = bluetoothSocket.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
String clientString = writer.toString();
Run Code Online (Sandbox Code Playgroud)

这个问题是它一直copy在线并且永远不会超过这一点。

所以,我的问题是,这些方法之间有什么不同,为什么我会得到不同的结果?

客户端的代码是(C# Using 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();
}
Run Code Online (Sandbox Code Playgroud)

Zor*_*art 3

我猜测 IOUtils 类来自 Apache Commons IO。它从 inputStream 复制到 writer,直到到达流的末尾(从流上的 read 方法返回 -1)。您的第一个方法只是尝试读取最多 1024 个字节,然后继续。

inputStream.read(buffer)还将返回读取的字节数。因此,当您创建字符串时,您可以使用它:

int read = inputStream.read(buffer);    
String clientString = new String(buffer, 0, read, "UTF-8")
Run Code Online (Sandbox Code Playgroud)

您还需要检查 read 方法是否返回 -1 表示已到达流末尾。