文件分割与合并

文件分割与合并

关闭流的代码(会在下面被调用)

FileUtil.java

package cn.Split;

import java.io.Closeable;
import java.io.IOException;

public class FileUtil {
/*
 * 工具类关闭流
 * 可变参数:... 只能形参最后一个位置,处理方式与数组一致
 * 
 */
    public static void close(Closeable ... io) {
        for(Closeable temp:io) {
            if(null!=temp) {
                try {
                    temp.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    /*
     * 使用泛型方法
     */
    public static <T extends Closeable> void closrAll(T ...io) {
        for(Closeable temp:io) {
            if(null!=temp) {
                try {
                    temp.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

分割文件代码

SplitFile.java

package cn.Split;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class SplitFile {
    //文件的路径 
    private String filePath;
    //文件名
    private String fileName;
    //文件大小
    private long length;
    //块数
    private int size;
    //每一块的大小
    private long blockSize;
    //每块的名称
    private List<String> blockPath;
    
    public SplitFile() {
        blockPath=new ArrayList<String>();
    }
    public SplitFile(String filePath) {
        this(filePath,1024);
        
    }
    public SplitFile(String filePath,long blockSize) {
        this();
        this.filePath=filePath;
        this.blockSize=blockSize;
        init();
        
    }
    /*
     * 初始化操作,计算块数、确定文件名
     */
    public void init() {
        File src=null;
        //健壮性
        if(null==filePath ||!(((src=new File(filePath)).exists() ))) {
            return;
        }
        if(src.isDirectory()) {
            return ;
        }
        //文件名
        this.fileName=src.getName();
        //计算块数  实际大小与每块大小
        this.length=src.length();
        //修正 每块大小
        if(this.blockSize>length) {
            this.blockSize=length;
        }
        //确定块数
        size=(int)Math.ceil(length*1.0/this.blockSize);
        
    }
    private void initPathName(String destPath) {
        for(int i=0;i<size;i++) {
            this.blockPath.add(destPath+"/"+this.fileName+".part"+i);
        }
    }
    /*
     * 文件分割
     * 1.起始位置
     * 2.实际大小
     * @param destPath  分割文件存放目录
     */
    public void split(String destPath) {
        //确定文件的路径
        initPathName(destPath);
        long  beginPos=0;  //起始点
        long actualBlockSize=blockSize; //实际大小
        
        //计算所有块的大小、位置、索引
        for(int i=0;i<size;i++) {
            if(i==size-1) {   //最后一块
                actualBlockSize=this.length-beginPos;
            }
            splitDetail(i,beginPos,actualBlockSize);
            beginPos+=actualBlockSize;  //本次的终点,下一次的起点
        }
    }
    /*
     * 文件的分割  输入输出
     * 文件拷贝
     */
    private void splitDetail(int idx,long beginPos,long actualBlockSize) {   //第几个,起始点,实际大小
        //1.创建源
        File src=new File(this.filePath);      //源文件
        File dest=new File(this.blockPath.get(idx));    //目标文件
        //2.选择流
        RandomAccessFile raf=null;      //输入流
        BufferedOutputStream bos=null;  //输出流
        try {
            raf=new RandomAccessFile(src,"r");
            bos=new BufferedOutputStream(new FileOutputStream(dest));
            //读取文件
            raf.seek(beginPos);
            //缓冲区
            byte[]flush=new byte[1024];
            //接收长度
            int len=0;
            while(-1!=(len=raf.read(flush))) {
                
                if(actualBlockSize-len>=0) {
                    //写出
                    bos.write(flush,0,len);
                    actualBlockSize-=len;  //剩余量
                }else { //写出最后一次的剩余量
                    bos.write(flush,0,(int)actualBlockSize);
                    break;
                }
                
            }
            
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        finally{
            FileUtil.close(bos,raf);
        }
    }
    
    
    
    public static void main(String[] args) {
        SplitFile split =new SplitFile("C:/Users/Administrator/Desktop/sun/a.txt",1);
        System.out.println(split.size);
        split.split("C:/Users/Administrator/Desktop/sun/s");
        
    }
}

效果

将a.txt文件分割为:

 文件的分割与合并完整代码

package cn.Split;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class SplitFile {
    //文件的路径 
    private String filePath;
    //文件名
    private String fileName;
    //文件大小
    private long length;
    //块数
    private int size;
    //每一块的大小
    private long blockSize;
    //分割后的存放目录
    private String destBlockPath;
    //每块的名称
    private List<String> blockPath;
    
    public SplitFile() {
        blockPath=new ArrayList<String>();
    }
    public SplitFile(String filePath,String destBlockPath) {
        this(filePath,destBlockPath,1024);
        
    }
    public SplitFile(String filePath,String destBlockPath,long blockSize) {
        this();
        this.filePath=filePath;
        this.destBlockPath=destBlockPath;
        this.blockSize=blockSize;
        init();
        
    }
    /*
     * 初始化操作,计算块数、确定文件名
     */
    public void init() {
        File src=null;
        //健壮性
        if(null==filePath ||!(((src=new File(filePath)).exists() ))) {
            return;
        }
        if(src.isDirectory()) {
            return ;
        }
        //文件名
        this.fileName=src.getName();
        //计算块数  实际大小与每块大小
        this.length=src.length();
        //修正 每块大小
        if(this.blockSize>length) {
            this.blockSize=length;
        }
        //确定块数
        size=(int)Math.ceil(length*1.0/this.blockSize);
        //确定文件的路径
        initPathName();
    }
    private void initPathName() {
        for(int i=0;i<size;i++) {
            this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
        }
    }
    /*
     * 文件分割
     * 1.起始位置
     * 2.实际大小
     * @param destPath  分割文件存放目录
     */
    public void split() {
        long  beginPos=0;  //起始点
        long actualBlockSize=blockSize; //实际大小
        
        //计算所有块的大小、位置、索引
        for(int i=0;i<size;i++) {
            if(i==size-1) {   //最后一块
                actualBlockSize=this.length-beginPos;
            }
            splitDetail(i,beginPos,actualBlockSize);
            beginPos+=actualBlockSize;  //本次的终点,下一次的起点
        }
    }
    /*
     * 文件的分割  输入输出
     * 文件拷贝
     */
    private void splitDetail(int idx,long beginPos,long actualBlockSize) {   //第几个,起始点,实际大小
        //1.创建源
        File src=new File(this.filePath);      //源文件
        File dest=new File(this.blockPath.get(idx));    //目标文件
        //2.选择流
        RandomAccessFile raf=null;      //输入流
        BufferedOutputStream bos=null;  //输出流
        try {
            raf=new RandomAccessFile(src,"r");
            bos=new BufferedOutputStream(new FileOutputStream(dest));
            //读取文件
            raf.seek(beginPos);
            //缓冲区
            byte[]flush=new byte[1024];
            //接收长度
            int len=0;
            while(-1!=(len=raf.read(flush))) {
                
                if(actualBlockSize-len>=0) {
                    //写出
                    bos.write(flush,0,len);
                    actualBlockSize-=len;  //剩余量
                }else { //写出最后一次的剩余量
                    bos.write(flush,0,(int)actualBlockSize);
                    break;
                }
                
            }
            
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        finally{
            FileUtil.close(bos,raf);
        }
    }
    
    /*
     * 文件的合并
     */
    public void merge(String destPath) {
        //1、创建源
        File dest=new File(destPath);
        //2、选择流
        BufferedOutputStream bos=null;
        try {
            bos=new BufferedOutputStream(new FileOutputStream(dest,true));  //追加
            BufferedInputStream bis=null;
            for(int i=0;i<this.blockPath.size();i++) {
                    bis=new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i))));
                    //缓冲区
                    byte[]flush=new byte[1024];
                    //接收长度
                    int len=0;
                    while(-1!=(len=bis.read(flush))) {
                        System.out.println(new String(flush,0,len));
                        bos.write(flush,0,len);
                    }
                    bos.flush();
                    FileUtil.close(bis);
                }
              }catch (FileNotFoundException e) {
                    
                    e.printStackTrace();
                } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                FileUtil.close(bos);
            }
            
        
    }
    
    
    
    public static void main(String[] args) {
        SplitFile split =new SplitFile("C:/Users/Administrator/Desktop/sun/a.txt","C:/Users/Administrator/Desktop/sun/s",1);
//        System.out.println(split.size);
        split.split();
        split.merge("C:/Users/Administrator/Desktop/sun/s/a.java ");
    }
}

效果:

 

posted on 2019-07-23 19:43  Mentality  阅读(533)  评论(0编辑  收藏  举报