1. 程式人生 > >檔案的分割與合併

檔案的分割與合併

import java.io.*;
import java.util.*;
public class MySplitFile {
    private String srcPath;//被分割的檔案目錄
    private String destPath;//分割的目的資料夾
    private String fileName;//分割的檔名
    private long begin;//讀取起點
    private long length;//被分割檔案的長度
    private long blockSize;//分割塊的大小
    private List<String> blockPath;//分割檔案的目錄
    private int size;//被分割的塊數

    public MySplitFile() {
        blockPath = new ArrayList<>();
    }

    public MySplitFile(String srcPath,String destPath,long blockSize) {
        this();
        this.blockSize = blockSize;
        this.srcPath=srcPath;
        this.destPath=destPath;
        init();
    }
    public void init(){
        File src=null;
        if(null==this.srcPath||!(src=new File(srcPath)).exists()){
            return;
        }
        if(src.isDirectory()) {
            return;
        }
        this.fileName=src.getName();
        length=src.length();
        this.size=(int)(Math.ceil(length*1.0/blockSize));//計算共有多少塊
        splitPath(destPath);
    }

    public void splitPath(String destPath){
        for(int i=0;i<size;i++){
            blockPath.add(destPath+"/"+fileName+i+".txt");//分割檔案的目錄
        }
    }

    public MySplitFile(String filePath,String destPath) {
        this(filePath,destPath,1024);//預設分割塊的大小為1024個位元組
    }
    public void split(){
        splitPath(destPath);
        long actualBlockSize=blockSize;
        for(int i=0;i<size;i++){
            if(i==size-1){
                actualBlockSize=length-begin;//最後一塊的大小
            }
            splitDetail(i,actualBlockSize);
            begin+=actualBlockSize;//計算分割起點

        }

    }
    public void splitDetail(int i,long actualBlockSize) {
        //資料來源
        File src=new File(srcPath);
        //選擇流
        RandomAccessFile raf=null;
        BufferedOutputStream bos=null;

        try {
            raf=new RandomAccessFile(src,"r");
            bos=new BufferedOutputStream(new FileOutputStream(new File(blockPath.get(i))));
            raf.seek(begin);
            byte[] flush=new byte[1024];
            int len=0;
            while (-1!=(len=raf.read(flush))){
                if(actualBlockSize>len){
                    bos.write(flush,0,len);
                    actualBlockSize-=len;
                }else{
                    bos.write(flush,0,(int)actualBlockSize);
                    break;
                }
            }
            bos.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bos.close();
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
    public void merge(String destPath){//檔案的合併
        //資料來源
        for(int i=0;i<size;i++){
            mergeDetail(blockPath.get(i),destPath);
        }


    }
    public void mergeDetail(String src,String destPath){
        //資料來源
        File file=new File(src);
        File dest=new File(destPath);
        //選擇流
        InputStream is=null;
        BufferedOutputStream bos=null;

        try {
            is=new BufferedInputStream(new FileInputStream(file));
            bos=new BufferedOutputStream(new FileOutputStream(dest,true));
            byte[] flush=new byte[1024];
            int len=0;
            while(-1!=(len=is.read(flush))){
                bos.write(flush,0,len);
            }
            bos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bos.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

    public static void main(String[] args) {
        MySplitFile mySplitFile=new MySplitFile("D:/test.txt","D:/a/b",10);
        //mySplitFile.split();
        mySplitFile.merge("D:/test2.txt");
    }
}