在java多個線程下載文件或處理較大文件是可能會切分成多個文件,處理完成後需要合併成一個文件。
Java中合併子文件最容易想到的就是利用BufferedStream進行讀寫。
利用BufferedStream合併多個文件
public static boolean mergeFiles(String[] fpaths, String resultPath) { if (fpaths == null || fpaths.length < 1 || TextUtils.isEmpty(resultPath)) { return false; } if (fpaths.length == 1) { return new File(fpaths[0]).renameTo(new File(resultPath)); } File[] files = new File[fpaths.length]; for (int i = 0; i < fpaths.length; i ++) { files[i] = new File(fpaths[i]); if (TextUtils.isEmpty(fpaths[i]) || !files[i].exists() || !files[i].isFile()) { return false; } } File resultFile = new File(resultPath); try { int bufSize = 1024; BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(resultFile)); byte[] buffer = new byte[bufSize]; for (int i = 0; i < fpaths.length; i ++) { BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(files[i])); int readcount; while ((readcount = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, readcount); } inputStream.close(); } outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } for (int i = 0; i < fpaths.length; i ++) { files[i].delete(); } return true; }
利用nio FileChannel合併多個文件
BufferedStream的合併操作是一個循環讀取子文件內容然後複製寫入最終文件的過程,此過程會從文件系統中讀取數據到內存中,之後再寫入文件系統,比較低效。
一種更高效的合併方式是利用Java nio庫中FileChannel類的transferTo方法進行合併。此方法可以利用很多操作系統直接從文件緩存傳輸字節的能力來優化傳輸速度。
實現方法:
public static boolean mergeFiles(String[] fpaths, String resultPath) { if (fpaths == null || fpaths.length < 1 || TextUtils.isEmpty(resultPath)) { return false; } if (fpaths.length == 1) { return new File(fpaths[0]).renameTo(new File(resultPath)); } File[] files = new File[fpaths.length]; for (int i = 0; i < fpaths.length; i ++) { files[i] = new File(fpaths[i]); if (TextUtils.isEmpty(fpaths[i]) || !files[i].exists() || !files[i].isFile()) { return false; } } File resultFile = new File(resultPath); try { FileChannel resultFileChannel = new FileOutputStream(resultFile, true).getChannel(); for (int i = 0; i < fpaths.length; i ++) { FileChannel blk = new FileInputStream(files[i]).getChannel(); resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size()); blk.close(); } resultFileChannel.close(); } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } for (int i = 0; i < fpaths.length; i ++) { files[i].delete(); } return true; }
[hongdian2012 ] java合併多個文件的兩種方法已經有221次圍觀