InputStream in.read() 的行为与预期不同
InputStream in.read() behaving differently than expected
我正在尝试使用 TCP 将文本文件传输到另一台服务器,但它的行为与预期不同。发送数据的代码是:
System.out.println("sending file name...");
String outputFileNameWithDelimiter = outputFileName + "\r\n"; //These 4 lines send the fileName with the delimiter
byte[] fileNameData = outputFileNameWithDelimiter.getBytes("US-ASCII");
outToCompression.write(fileNameData, 0, fileNameData.length);
outToCompression.flush();
System.out.println("sending content...");
System.out.println(new String(buffer, dataBegin, dataEnd-dataBegin));
outToCompression.write(buffer, dataBegin, dataEnd-dataBegin); //send the content
outToCompression.flush();
System.out.println("sending magic String...");
byte[] magicStringData = "--------MagicStringCSE283Miami".getBytes("US-ASCII"); //sends the magic string to tell Compression server the data being sent is done
outToCompression.write(magicStringData, 0, magicStringData.length);
outToCompression.flush();
因为这是 TCP,你不能像在 UDP 中那样发送离散数据包,我希望所有数据都在输入流中,我可以只使用定界符来分隔文件名、内容和结束字符串然后每个 in.read() 只会给我下一个后续数据量。
相反,这是我每次读取时获得的数据:
On the first in.read() byteBuffer appears to only have "fileName\r\n".
On the second in.read() byteBuffer still has the same information.
On the third in.read() byteBuffer now holds the content I sent.
On the fourth in.read() byteBuffer holds the content I sent minus a few letters.
On the fifth in.read() I get the magicString + part of the message.
每次从网络服务器发送时我都会刷新,但输入流似乎没有实现可刷新。
谁能解释为什么会这样?
编辑:
这就是我读入内容的方式。基本上这是一个循环,然后写入文件。
in.read(byteBuffer, 0, BUFSIZE);
如果您的期望是读取将填充缓冲区,或者接收到由对等方发送的单个 write()
所发送的内容,那么您的期望在这里有问题,而不是 read().
未指定一次传输超过一个字节,并且无法保证保留写入边界。
如果不将 read()
的结果存储到变量中,就不可能编写正确的代码。
当您从 InputStream
中读取数据时,您将给它一个要写入的字节数组(以及可选的偏移量和要读取的最大数量)。 InputStream
不保证数组将填充新数据。 return值为实际读入的字节数。
您的示例中发生的情况是这样的:
- 第一个 TCP 数据包来自
"fileName\r\n"
,被写入您的缓冲区,到目前为止一切正常。
- 您再次调用
read()
,但下一个数据包尚未到达。 read()
将 returned 0
,因为它不想阻塞直到数据到达。所以缓冲区仍然包含"fileName\r\n"
。编辑:正如所指出的,read()
总是阻塞,直到它读取至少一个字节。真的不知道为什么缓冲区没有改变。
- 读到第三遍,内容到了
- 内容的第一位被消息的第二部分覆盖,最后一位仍然包含旧消息的一部分(我想这就是你的意思)。
- 等等,你懂的
您需要检查 return 值,等待数据到达,并且只使用最后一个 read()
写入的缓冲区。
我正在尝试使用 TCP 将文本文件传输到另一台服务器,但它的行为与预期不同。发送数据的代码是:
System.out.println("sending file name...");
String outputFileNameWithDelimiter = outputFileName + "\r\n"; //These 4 lines send the fileName with the delimiter
byte[] fileNameData = outputFileNameWithDelimiter.getBytes("US-ASCII");
outToCompression.write(fileNameData, 0, fileNameData.length);
outToCompression.flush();
System.out.println("sending content...");
System.out.println(new String(buffer, dataBegin, dataEnd-dataBegin));
outToCompression.write(buffer, dataBegin, dataEnd-dataBegin); //send the content
outToCompression.flush();
System.out.println("sending magic String...");
byte[] magicStringData = "--------MagicStringCSE283Miami".getBytes("US-ASCII"); //sends the magic string to tell Compression server the data being sent is done
outToCompression.write(magicStringData, 0, magicStringData.length);
outToCompression.flush();
因为这是 TCP,你不能像在 UDP 中那样发送离散数据包,我希望所有数据都在输入流中,我可以只使用定界符来分隔文件名、内容和结束字符串然后每个 in.read() 只会给我下一个后续数据量。
相反,这是我每次读取时获得的数据:
On the first in.read() byteBuffer appears to only have "fileName\r\n".
On the second in.read() byteBuffer still has the same information.
On the third in.read() byteBuffer now holds the content I sent.
On the fourth in.read() byteBuffer holds the content I sent minus a few letters.
On the fifth in.read() I get the magicString + part of the message.
每次从网络服务器发送时我都会刷新,但输入流似乎没有实现可刷新。
谁能解释为什么会这样?
编辑: 这就是我读入内容的方式。基本上这是一个循环,然后写入文件。
in.read(byteBuffer, 0, BUFSIZE);
如果您的期望是读取将填充缓冲区,或者接收到由对等方发送的单个 write()
所发送的内容,那么您的期望在这里有问题,而不是 read().
未指定一次传输超过一个字节,并且无法保证保留写入边界。
如果不将 read()
的结果存储到变量中,就不可能编写正确的代码。
当您从 InputStream
中读取数据时,您将给它一个要写入的字节数组(以及可选的偏移量和要读取的最大数量)。 InputStream
不保证数组将填充新数据。 return值为实际读入的字节数。
您的示例中发生的情况是这样的:
- 第一个 TCP 数据包来自
"fileName\r\n"
,被写入您的缓冲区,到目前为止一切正常。 - 您再次调用
read()
,但下一个数据包尚未到达。。编辑:正如所指出的,read()
将 returned0
,因为它不想阻塞直到数据到达。所以缓冲区仍然包含"fileName\r\n"
read()
总是阻塞,直到它读取至少一个字节。真的不知道为什么缓冲区没有改变。 - 读到第三遍,内容到了
- 内容的第一位被消息的第二部分覆盖,最后一位仍然包含旧消息的一部分(我想这就是你的意思)。
- 等等,你懂的
您需要检查 return 值,等待数据到达,并且只使用最后一个 read()
写入的缓冲区。