0

我正在尝试在下面的第一个代码示例中执行类似的操作,它是非阻塞的,但它会提供损坏的文件。第二个例子工作正常,但它是阻塞的,如果你不从客户端(另一端)关闭输出流的套接字,这是这个服务器连接到的另一个设备,那么它将阻塞并且线程执行不会走得更远。

导致它每次都生成损坏文件的第一段代码有什么问题?

第一个示例代码,好主意,但会产生损坏的文件;

 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); 
 }
4

2 回答 2

1
  1. 测试bytesRead == -1应该在写入之前,而不是之后。
  2. 的长度参数write()应该是bytesRead
  3. 两者的偏移量参数read()write()应该为零。
于 2013-09-26T11:05:44.270 回答
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;
    }

如您所见,它几乎与您所说的第二个示例相同,即“块”。

于 2013-09-26T11:03:01.880 回答