2017-05-19 83 views
0

副本時我已經執行以下代碼複製文件(二進制文件) 代碼的java:使用NIO

private void copyFileWithChannels(File aSourceFile, File aTargetFile) { 
     log("Copying files with channels.");   
     FileChannel inChannel = null; 
     FileChannel outChannel = null; 
     FileInputStream inStream = null; 
     FileOutputStream outStream = null;  
     try { 
      inStream = new FileInputStream(aSourceFile); 
      inChannel = inStream.getChannel(); 
      outStream = new FileOutputStream(aTargetFile);   
      outChannel = outStream.getChannel(); 
      long bytesTransferred = 0; 
      while(bytesTransferred < inChannel.size()){ 
       bytesTransferred += inChannel.transferTo(0, inChannel.size(), outChannel); 
      } 
     } 
     catch(FileNotFoundException e){ 
      log.error("FileNotFoundException in copyFileWithChannels()",e); 
     } 
     catch (IOException e) { 
      log.error("IOException in copyFileWithChannels()",e);   
     } 
     catch (Exception e) { 
      log.error("Exception in copyFileWithChannels()",e); 
     } 
     finally { 
      try{ 
       if (inChannel != null) inChannel.close(); 
       if (outChannel != null) outChannel.close(); 
       if (inStream != null) inStream.close(); 
       if (outStream != null) outStream.close(); 
      }catch(Exception e){ 
       log.error("Exception in copyFileWithChannels() while closing the stream",e); 
      } 
     } 

    } 

我有一個zip文件測試代碼損壞的ZIP文件中創建。當我驗證文件時,我發現生成的文件已損壞(大小增加)。 源zip文件大約9GB。

回答

1

transferTo方法的第一個參數給出了從哪裏傳送的位置nsfer,而不是相對於流停止的地方,但相對於文件的開始。由於您將0放在那裏,因此它始終會從文件的開始處傳輸。因此,該行需要在他的回答中提到

bytesTransferred += inChannel.transferTo(bytesTransferred , inChannel.size(), outChannel); 

mavarazy他不知道,如果你使用inChannel.size()時,需要一個循環,因爲預期的是,如果你提供全尺寸會複製整個文件。但是,如果輸出通道的緩衝區空間不足,實際傳輸可能會少於所請求的字節數。所以你需要在他的第二個代碼片段中的循環。

+0

我已更正我的答案,謝謝 – mavarazy