我正在尝试执行类似下面代码的第一个示例,即非阻塞但它会提供损坏的文件。第二个例子工作正常,但是它是阻塞的,如果你没有关闭来自客户端(另一端)的输出流的套接字,这是该服务器连接的另一个设备,那么它将阻塞并且线程执行不会比那更远了。
导致它每次都产生损坏文件的第一段代码出了什么问题?
第一个示例代码,好主意但产生损坏的文件;
while(totalBytesRead < fileSizeFromClient){
int bytesRemaining = fileSizeFromClient - totalBytesRead;
int bytesRead = bufferedInputStream.read(buffer, totalBytesRead, bytesRemaining);
bufferedOutputStream.write(buffer, totalBytesRead, bytesRemaining);
if(bytesRead == -1){
break;
}else{
totalBytesRead += bytesRead;
}
}
第二个例子,代码卡住;块。所以我不能使用它,因为你必须从客户端杀死套接字以使代码执行继续超出这些代码行。但它产生完美无损的文件。
while((count = bufferedInputStream.read(buffer)) > 0){
bufferedOutputStream.write(buffer, 0, count);
}
答案 0 :(得分:1)
bytesRead == -1
的测试应该在写入之前,而不是遵循它。write()
的长度参数应为bytesRead
。read()
和write()
的偏移量参数应为零。答案 1 :(得分:0)
该行写入所有“剩余”字节,即使只读取了一个字节,如果read
返回-1表示输入结束,也可能写入一些内容:
bufferedOutputStream.write(buffer, totalBytesRead, bytesRemaining);
要仅写入已读取的字节,请将读取的字节数作为第三个参数传递。
int bytesRead = bufferedInputStream.read(buffer, totalBytesRead, bytesRemaining);
if (bytesRead == -1) {
break;
} else {
bufferedOutputStream.write(buffer, totalBytesRead, bytesRead);
totalBytesRead += bytesRead;
}
没有理由为什么第二个代码应该阻止而不是这个。
另请注意,这样您就可以创建正在传输的数据的内存中副本,如果缓冲区不够大,可能会占用大量内存或使程序失败ArrayIndexOutOfBoundsException
。如果这不是您的意图,则在读取和写入时应使用0
而不是totalBytesRead
作为数组偏移量,并将读取的字节数限制为缓冲区的大小。在这些转换之后,代码看起来像这样:
int bytesRead = bufferedInputStream.read(buffer);
if (bytesRead == -1) {
break;
} else {
bufferedOutputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
正如您所看到的,它与您的第二个示例几乎完全相同,您说的是“阻止”。