2015-08-16 158 views
0

我寫了一個下載程序,用於下載文本文件以及圖像。所以我將這些文件作爲二進制文件下載。許多下載工作得很好,但文本文件和許多圖像文件的某些部分已損壞。這些錯誤總是發生在相同的文件和相同的地方(只要我能夠分析文本文件時就能知道)。我用這個代碼下載:作爲二進制文件下載的Java文件已損壞

public File downloadFile(HttpURLConnection connection) { 
     return writeFileDataToFile(getFileData(connection)); 
    }  

    //downloads the data of the file and returns the content as string 
    private List<Byte> getFileData(HttpURLConnection connection) { 
     List<Byte> fileData = new ArrayList<>(); 

     try (InputStream input = connection.getInputStream()) { 
      byte[] fileChunk = new byte[8*1024]; 
      int bytesRead; 

      do { 
       bytesRead = input.read(fileChunk); 
       if (bytesRead != -1) { 
        fileData.addAll(Bytes.asList(fileChunk)); 
        fileChunk = new byte[8*1024]; 
       } 
      } while (bytesRead != -1); 

      return fileData; 
     } catch (IOException e) { 
      System.out.println("Receiving file at " + url.toString() + " failed"); 
      System.exit(1); 
      return null; //shouldn't be reached 
     } 
    } 

    //writes data to the file 
    private File writeFileDataToFile(List<Byte> fileData) { 

     if (!this.file.exists()) { 
      try { 
       this.file.getParentFile().mkdirs(); 
       this.file.createNewFile(); 
      } catch (IOException e) { 
       System.out.println("Error while creating file at " + file.getPath()); 
       System.exit(1); 
      } 
     } 

     try (OutputStream output = new FileOutputStream(file)) { 
      output.write(Bytes.toArray(fileData)); 
      return file; 
     } catch (IOException e) { 
      System.out.println("Error while accessing file at " + file.getPath()); 
      System.exit(1); 
      return null; 
     } 
    } 
+0

你假設'bytesRead'是'-1'或'8192',它是什麼說MTU約1500字節? –

回答

1

我可以建議你不要穿過字節的名單,因爲你從一個數組創建字節的列表,拿回來給字節數組,這是不非常有效。

此外,你錯誤地假定塊的大小(不需要8192字節)。

你爲什麼不只是做一些如:

private File writeFileDataToFile(HttpURLConnection connection) { 
    if (!this.file.exists()) { 
     try { 
      this.file.getParentFile().mkdirs(); 
      //this.file.createNewFile(); // not needed, will be created at FileOutputStream 
     } catch (IOException e) { 
      System.out.println("Error while creating file at " + file.getPath()); 
      //System.exit(1); 
      // instead do a throw of error or return null 
      throw new YourException(message); 
     } 
    } 
    OutputStream output = null; 
    InputStream input = null; 
    try { 
     output = new FileOutputStream(file): 
     input = connection.getInputStream(); 
     byte[] fileChunk = new byte[8*1024]; 
     int bytesRead; 
     while ((bytesRead = input.read(fileChunk)) != -1) { 
     output.write(fileChunk , 0, bytesRead); 
     } 
     return file; 
    } catch (IOException e) { 
     System.out.println("Receiving file at " + url.toString() + " failed"); 
     // System.exit(1); // you should avoid such exit 
     // instead do a throw of error or return null 
     throw new YourException(message); 
    } finally { 
     if (input != null) { 
     try { 
      input.close(); 
     } catch (Execption e2) {} // ignore 
     } 
     if (output != null) { 
     try { 
      output.close(); 
     } catch (Execption e2) {} // ignore 
     } 
    } 
} 
+0

謝謝!失敗的原因是每次添加整個fileChunk,即使它沒有被完全使用,是什麼導致向fileData添加錯誤的0字節。 – DevWurm

0

失敗被加入整個fileChunk陣列對文件數據的,即使它沒有完全被讀操作填補。

修復:

//downloads the data of the file and returns the content as string 
private List<Byte> getFileData(HttpURLConnection connection) { 
    List<Byte> fileData = new ArrayList<>(); 

    try (InputStream input = connection.getInputStream()) { 
     byte[] fileChunk = new byte[8*1024]; 
     int bytesRead; 

     do { 
      bytesRead = input.read(fileChunk); 
      if (bytesRead != -1) { 
       fileData.addAll(Bytes.asList(Arrays.copyOf(fileChunk, bytesRead))); 
      } 
     } while (bytesRead != -1); 

     return fileData; 
    } catch (IOException e) { 
     System.out.println("Receiving file at " + url.toString() + " failed"); 
     System.exit(1); 
     return null; //shouldn't be reached 
    } 
} 

凡有關的變化正在改變

if (bytesRead != -1) { 
    fileData.addAll(Bytes.asList(fileChunk)); 
    fileChunk = new byte[8*1024]; 
} 

if (bytesRead != -1) { 
    fileData.addAll(Bytes.asList(Arrays.copyOf(fileChunk, bytesRead))); 
}