java 實現大檔案分隔成多個小檔案
阿新 • • 發佈:2018-12-17
public class FileTest { /** * 檔案分隔器:給定檔案的路徑和每一塊要拆分的大小,就可以按要求拆分檔案 * 如果指定的塊給原檔案都還要大,為了不動原檔案,就生成另一個檔案,以.bak為字尾,這樣可以保證原檔案 * 如果是程式自動拆分為多個檔案,那麼字尾分別為".part序號",這樣就可以方便檔案的合併了 * 原理:很簡單,就是利用是輸入輸出流,加上隨機檔案讀取。 */ String FileName=null;//原檔名 long FileSize=0;//原檔案的大小 long BlockNum=0;//可分的塊數 /** * @param fileAndPath 原檔名及路徑 */ private void getFileAttribute(String fileAndPath)//取得原檔案的屬性 { File file=new File(fileAndPath); FileName=file.getName(); FileSize=file.length(); } /** * * @param blockSize 每一塊的大小 * @return 能夠分得的塊數 */ private long getBlockNum(long blockSize)//取得分塊數 { long fileSize=FileSize; if(fileSize<=blockSize)//如果分塊的小小隻夠分一個塊 return 1; else { if(fileSize%blockSize>0) { return fileSize/blockSize+1; } else return fileSize/blockSize; } } /** * * @param fileAndPath 原檔案及完整路徑 * @param currentBlock 當前塊的序號 * @return 現在拆分後塊的檔名 */ private String generateSeparatorFileName(String fileAndPath,int currentBlock)//生成折分後的檔名,以便於將來合將 { return fileAndPath+".part"+currentBlock; } /** * * @param fileAndPath 原檔案及完整路徑 * @param fileSeparateName 檔案分隔後要生成的檔名,與原檔案在同一個目錄下 * @param blockSize 當前塊要寫的位元組數 * @param beginPos 從原檔案的什麼地方開始讀取 * @return true為寫入成功,false為寫入失敗 */ private boolean writeFile(String fileAndPath,String fileSeparateName,long blockSize,long beginPos)//往硬碟寫檔案 { RandomAccessFile raf=null; FileOutputStream fos=null; byte[] bt=new byte[1024]; long writeByte=0; int len=0; try { raf = new RandomAccessFile(fileAndPath,"r"); raf.seek(beginPos); fos = new FileOutputStream(fileSeparateName); while((len=raf.read(bt))>0) { if(writeByte<blockSize)//如果當前塊還沒有寫滿 { writeByte=writeByte+len; if(writeByte<=blockSize) fos.write(bt,0,len); else { len=len-(int)(writeByte-blockSize); fos.write(bt,0,len); } } } fos.close(); raf.close(); } catch (Exception e) { e.printStackTrace(); try { if(fos!=null) fos.close(); if(raf!=null) raf.close(); } catch(Exception f) { f.printStackTrace(); } return false; } return true; } /** * @param fileAndPath 原文路徑及檔名 * @param blockSize 要拆分的每一塊的大小 * @return true為拆分成功,false為拆分失敗 */ private boolean separatorFile(String fileAndPath,long blockSize)//折分檔案主函式 { getFileAttribute(fileAndPath);//將檔案的名及大小屬性取出來 //System.out.println("FileSize:"+FileSize); //System.out.println("blockSize:"+blockSize); BlockNum=getBlockNum(blockSize);//取得分塊總數 //System.out.println("BlockNum:"+BlockNum); //System.exit(0); if(BlockNum==1)//如果只能夠分一塊,就一次性寫入 blockSize=FileSize; long writeSize=0;//每次寫入的位元組 long writeTotal=0;//已經寫了的位元組 String FileCurrentNameAndPath=null; for(int i=1;i<=BlockNum;i++) { if(i<BlockNum) writeSize=blockSize;//取得每一次要寫入的檔案大小 else writeSize=FileSize-writeTotal; if(BlockNum==1) FileCurrentNameAndPath=fileAndPath+".bak"; else FileCurrentNameAndPath=generateSeparatorFileName(fileAndPath,i); //System.out.print("本次寫入:"+writeSize); if(!writeFile(fileAndPath,FileCurrentNameAndPath,writeSize,writeTotal))//迴圈往硬碟寫檔案 return false; writeTotal=writeTotal+writeSize; //System.out.println(" 總共寫入:"+writeTotal); } return true; } public static void main(String[] args) { FileTest separator = new FileTest(); String fileAndPath="f://abc.txt";//檔名及路徑 long blockSize=200*1024;//每一個檔案塊的大小,大小是按位元組計算 if(separator.separatorFile(fileAndPath,blockSize)) { System.out.println("檔案折分成功!"); } else { System.out.println("檔案折分失敗!"); } } }