Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在块中读取字节时套接字InputStream出现故障_Java_File_Sockets_Byte_Inputstream - Fatal编程技术网

Java 在块中读取字节时套接字InputStream出现故障

Java 在块中读取字节时套接字InputStream出现故障,java,file,sockets,byte,inputstream,Java,File,Sockets,Byte,Inputstream,我正在通过套接字连接编写简单的文件传输,我遇到了一个问题 以字节块形式下载文件时。当我一次读取一个字节时,一切正常,但当我尝试读取512字节的块时,在下载文件的所有字节后(我知道长度,这要归功于我的头),套接字开始接收一些随机字节,最终出现崩溃,因为2x“%”已找到,并且服务器尝试计算传入消息的长度,但没有可开始的长度 @Override public void run() { while (client.isConnected() && !client.is

我正在通过套接字连接编写简单的文件传输,我遇到了一个问题 以字节块形式下载文件时。当我一次读取一个字节时,一切正常,但当我尝试读取512字节的块时,在下载文件的所有字节后(我知道长度,这要归功于我的头),套接字开始接收一些随机字节,最终出现崩溃,因为2x“%”已找到,并且服务器尝试计算传入消息的长度,但没有可开始的长度

 @Override
  public void run() {

      while (client.isConnected() && !client.isClosed() && !client.isInputShutdown()){
          try {
                readResponse();
                clientWriter.write("0%"); /// IF IT CATCHES EXCEPTION SOCKET CLOSED ON THE OTHER SIDE(DON'T KNOW HOW TO CHECK IT IN ANOTHER WAY)
           } 
          catch (IOException e) {
               System.out.println(e.toString());
               return;
           } 
          catch (InterruptedException e) {
               System.out.println(e.toString());
               return;
           } 
      }

   }

private void readResponse() throws IOException, InterruptedException {

       int length = 0;
       int ch;
       FileOutputStream file = new FileOutputStream("holder");
       boolean bWrite = false;
       StringBuilder name = new StringBuilder();
       int percentageCount = 0;
       String filename="";
       length = 0;
       int l = 0;
       int old = 0;
       while ((ch=client.getInputStream().read())!=-1){
           if (!bWrite) {
               name.append(Character.toChars(ch));
           }
           if (ch==37 && !bWrite){
               if (percentageCount<1){
                   percentageCount++;
               } else {
                filename = name.toString();
                length = Integer.parseInt(filename.substring(0,filename.indexOf("%")));
                l = length;
                filename = filename.substring(filename.indexOf("%")+1);
                filename = filename.substring(0,filename.indexOf("%"));
               file = new FileOutputStream(filename);
               bWrite = true;
               break;
               }
           }
       }
       byte[] bytes = new byte[512];
       while (length>=512){
           client.getInputStream().read(bytes, 0, 512);
           file.write(bytes, 0, 512);
           length-=512;
       }
       if (length>0){
           bytes = new byte[length];
           client.getInputStream().read(bytes,0,length);
           file.write(bytes,0,length);
           length = 0;
       }
       file.flush();
       file.close();
    }
@覆盖
公开募捐{
while(client.isConnected()&&&!client.isClosed()&&!client.isInputShutdown()){
试一试{
readResponse();
clientWriter.write(“0%”;///如果它捕获到另一侧关闭的异常套接字(不知道如何用另一种方式检查它)
} 
捕获(IOE异常){
System.out.println(例如toString());
返回;
} 
捕捉(中断异常e){
System.out.println(例如toString());
返回;
} 
}
}
private void readResponse()引发IOException、InterruptedException{
整数长度=0;
int-ch;
FileOutputStream文件=新的FileOutputStream(“持有者”);
布尔bWrite=false;
StringBuilder名称=新的StringBuilder();
int percentageCount=0;
字符串filename=“”;
长度=0;
int l=0;
int old=0;
而((ch=client.getInputStream().read())!=-1){
如果(!bWrite){
name.append(Character.toChars(ch));
}
if(ch==37&&!bWrite){
如果(百分比计数=512){
client.getInputStream().read(字节,0,512);
写入(字节,0,512);
长度-=512;
}
如果(长度>0){
字节=新字节[长度];
client.getInputStream().read(字节,0,长度);
file.write(字节,0,长度);
长度=0;
}
flush()文件;
file.close();
}

代码的最后一部分可以更改为(未测试):

byte[]bytes=新字节[512];
InputStream=client.getInputStream();
而(长度>0){
int read=is.read(bytes,0,Math.min(bytes.length,length));
如果(读取>0){
文件写入(字节,0,读取);
长度-=读取;
}
如果(读取<0)
抛出新的IOException(“在读取所有数据之前达到结束”;
}
这将正确地检查返回的大小,避免两个循环并检查流的结尾


BTW2:
getInputStream()
相当重,只能执行一次(我示例中的
应该在方法开始时检索,尤其是在读取循环之前)。

btw我的头格式是:%%您需要先清理循环。不要执行
client.getInputStream().read()之类的操作
并尝试删除与您的问题无关的所有代码。很难找到想要读取所有代码的人。一个明显的问题是,您读取了512字节的缓冲区,但没有实际检查返回了多少字节。您必须使用read(仅写入readLen字节)的返回值。这种情况在您的代码中发生了2次。尤其是长度较大的第二次将失败。是否删除任何其他内容?我知道这有点混乱,但应该都能正常工作如果一切正常,那么您为什么要问?:)还有一个问题,如何最好地检测另一方面是否关闭了套接字?除非您发送/接收某种形式的心跳消息,否则无法在所有情况下检测到它。您可以为套接字打开,但这将仅在数小时后检测(典型的操作系统设置)。但是,如果操作系统检测到它,您将在读取时获得-1,或在写入时获得异常。您应该在协议中包含一条“我完成了”消息,以便可以完全关闭。@Peter Lawrey有一个-1的示例:
   byte[] bytes = new byte[512];
   InputStream is = client.getInputStream();
   while (length>0) {
       int read = is.read(bytes, 0, Math.min(bytes.length, length));
       if (read > 0) {
         file.write(bytes, 0, read);
         length-=read;
       }
       if (read < 0)
         throw new IOException("end reached before all data read"; 
   }