package cn.com;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.RandomAccessFile;//檔案的拆分和組合//步驟://1 依據源檔案大小和每塊的大小計算出塊數//2 將每一塊寫到一個對應的檔案public class FileSeparatorAndUnite {long rawFileSize;long blocksNumber;String rawFileName=null;String [] allPaths=null;public static void main(String[] args) { FileSeparatorAndUnite test=new FileSeparatorAndUnite(); //拆分檔案 String [] allPaths=test.separatorFile("F:\\2.jpg", 1024*10); //組合檔案 test.uniteFile(allPaths, "F:\\99.jpg");}/** * @param rawFilePath 待拆分檔案的路徑 * @param perBlockSize 拆分後每份的大小 * @return 各部分路徑的數組集合 */private String[] separatorFile(String rawFilePath,long perBlockSize){File rawFile=new File(rawFilePath);rawFileName=rawFile.getName();rawFileSize=rawFile.length();blocksNumber=getBlocksNumber(rawFileSize,perBlockSize);allPaths=new String[(int)blocksNumber];if (blocksNumber==1) {perBlockSize=rawFileSize;}long perPartSize=0;long perPartBeginPosition=0;String perPartPath=null;for (int i = 1; i <=blocksNumber; i++) {if (i<blocksNumber) {//每一塊的大小就為perBlockSizeperPartSize=perBlockSize;} else {//最後一塊的大小為總大小-該塊的起始位置 perPartSize=rawFileSize-perPartBeginPosition;}//得到每一塊的pathif (blocksNumber==1) {perPartPath=rawFilePath+".bat";} else {perPartPath=getPerPartFilePath(rawFilePath, i);}//操作每一塊//第一次調用時perPartBeginPosition當然為0System.out.println("該Block開始位置:perPartBeginPosition="+perPartBeginPosition);writePerPartToFile(rawFilePath, perPartPath, perPartSize, perPartBeginPosition); //計算每一塊的在原檔案中的起始位置.perPartBeginPosition=perPartBeginPosition+perPartSize;//儲存每一塊的路徑allPaths[i-1]=perPartPath;System.out.println("該Block大小:perPartSize="+perPartSize);}return allPaths;}/** * @param rawFilePath 原檔案路徑 * @param perPartFilePath 每部分對應的路徑 * @param blockSize 每部分的塊大小 * @param beginPosition 每部分在原檔案中的開始位置 * @return * * rafForReader.read(buffer, 0, everyTimeReadLen) * 表示:向buffer中讀入everyTimeReadLen個位元組 */public boolean writePerPartToFile(String rawFilePath,String perPartFilePath,long blockSize,long beginPosition){RandomAccessFile rafForReader=null;RandomAccessFile rafForWriter=null;boolean isContinueReading=true;//每次應該讀取的位元組數 int everyTimeReadLen=0;byte [] buffer=new byte[1024*8];try {rafForReader=new RandomAccessFile(rawFilePath, "r");rafForReader.seek(beginPosition);File perPartFile=new File(perPartFilePath);rafForWriter=new RandomAccessFile(perPartFile, "rw");//設定檔案大小rafForWriter.setLength(blockSize);int writerOff=0;//設定第一次read()應該讀取的位元組if (blockSize>buffer.length) {everyTimeReadLen=buffer.length;}else {everyTimeReadLen=(int)blockSize;}while (rafForReader.read(buffer, 0, everyTimeReadLen)!=-1&&isContinueReading){ rafForWriter.seek(writerOff); writerOff+=everyTimeReadLen; rafForWriter.write(buffer, 0, everyTimeReadLen); //動態改變下次該讀取的位元組數 if (blockSize-writerOff>buffer.length) {everyTimeReadLen=buffer.length;}else {everyTimeReadLen=(int)blockSize-writerOff;} //讀取完畢 if (everyTimeReadLen==0) {isContinueReading=false;}}rafForReader.close();rafForWriter.close();} catch (Exception e) {return false;}return true;}/** * @param rawFileSize 原檔案大小 * @param perBlockSize 每塊的大小 * @return 拆分後塊數 */public long getBlocksNumber(long rawFileSize,long perBlockSize){if (rawFileSize<=perBlockSize) {return 1;} else { if (rawFileSize%perBlockSize==0) {return (rawFileSize/perBlockSize);} else { return (rawFileSize/perBlockSize)+1;}}}/** * @param rawFilePath 原檔案路徑 * @param blockNumer 當前塊號碼 * @return 當前塊對應的路徑 */public String getPerPartFilePath(String rawFilePath,int blockNumer){String perPartFilePath=rawFilePath+".part"+blockNumer;return perPartFilePath;}/** * @param partsPaths 各部分路徑 * @param unitedFilePath 合并後檔案路徑 */public void uniteFile(String [] partsPaths,String unitedFilePath){try {File perPartFile=null;File unitedFile=new File(unitedFilePath);FileOutputStream fos=new FileOutputStream(unitedFile);FileInputStream fis=null;for (int i = 0; i < partsPaths.length; i++) {perPartFile=new File(partsPaths[i]);fis=new FileInputStream(perPartFile);byte [] buffer=new byte[1024*8];int len=0;while ((len=fis.read(buffer))!=-1) {fos.write(buffer, 0, len);}}fis.close();fos.close();} catch (Exception e) {}}}