文件分割、合并、序列流

文件分割:下载工具就是用这个原理来下载的;比如一部电影,有5个人同时在下,那么就把
 *   这个电影分割成5部分,每人下一部分然后再合起来,这就是为什么下载这么快。
 *   但是必需先对这个文件进行分割。
 *    randomAccessFile:随机访问:支持读取和写入随机访问文件
 *    sequenceInputStream:序列流,用于文件的合并

分割文件

  //分割文件后,放到其他文件里
    public static void test1(int i,int begin,int actualSize) throws IOException{
        RandomAccessFile rf = new RandomAccessFile(
                new File("src/SOA.txt"),"r");//参数r是读取
        RandomAccessFile rf2 = new RandomAccessFile(
                new File("src/dest/"+i+"SOA.txt"),"rw");//参数rw是写入
        rf.seek(begin);//设置文件指针偏移,从该文件的开头测量,发生下一次读取或写入
        byte[] datas = new byte[1024];
        int len = -1;
        while((len = rf.read(datas))!=-1){
            if(actualSize>len){//获取本次读取的所有内容
                rf2.write(datas,0,len);
                actualSize -=len;
            }else{
                rf2.write(datas,0,actualSize);
                 break;
            }
        }
        rf2.close();
        rf.close();
    }

如何分块的方法

 //分块
    public static void test() throws IOException {
        File file = new File("src/SOA.txt");
        //总长度
        long len = file.length();
        //每块大小
        int blockSize = 1024;
        //多少块  ceil向上取整
        int size = (int)Math.ceil(len*1.0/blockSize);
        int begin = 0;//起始位置
        int actualSize = (int)(blockSize>len?len:blockSize);//实际大小
        for (int i = 0; i < size; i++) {
            begin =blockSize*i;
            if(i==size-1){//最后一块的时候
                actualSize = (int)len;
            }else{
                actualSize =blockSize;
                len -=actualSize;
            }
            System.out.println(i+"---"+begin+"----"+actualSize);
            test1(i,begin,actualSize);
        }

    }

 

面向对象思想 封装分割方法

 //源头
    private File src;
    //目的地
    private String destDir;
    //所以分割后的文件路径
    private List<String> destPaths;
    //每块大小
    private  int blockSize;
    //块数
    private int size;

    public TestFileSplit(String src, String destDir, int blockSize) {
        this.src = new File(src);
        this.destDir = destDir;
        this.blockSize = blockSize;
        this.destPaths = new ArrayList<String>();
        init();
    }


    //初始化
    private void init(){
        //总长度
        long len = this.src.length();
        //每块大小
        int blockSize = 1024;
        //多少块  ceil向上取整
        this.size = (int)Math.ceil(len*1.0/blockSize);
        //路劲
        for (int i = 0; i < size; i++) {
            this.destPaths.add(this.destDir+"/"+i+"-"+this.src.getName());
        }
    }
 private   void test1(int i,int begin,int actualSize) throws IOException{
        RandomAccessFile rf = new RandomAccessFile(this.src,"r");//参数r是读取
        RandomAccessFile rf2 = new RandomAccessFile(this.destPaths.get(i),"rw");//参数rw是写 
      入
        rf.seek(begin);//设置文件指针偏移,从该文件的开头测量,发生下一次读取或写入
        byte[] datas = new byte[1024];
        int len = -1;
        while((len = rf.read(datas))!=-1){
            if(actualSize>len){//获取本次读取的所有内容
                rf2.write(datas,0,len);
                actualSize -=len;
            }else{
                rf2.write(datas,0,actualSize);
                 break;
            }
        }
        rf2.close();
        rf.close();
    }
 public  void test() throws IOException {
        //总长度
        long len = src.length();

        int begin = 0;//起始位置
        int actualSize = (int)(blockSize>len?len:blockSize);//实际大小
        for (int i = 0; i < size; i++) {
            begin =blockSize*i;
            if(i==size-1){//最后一块的时候
                actualSize = (int)len;
            }else{
                actualSize =blockSize;
                len -=actualSize;
            }
            test1(i,begin,actualSize);
        }

    }

调用:

 TestFileSplit tfs = new TestFileSplit("src/SOA.txt", "src/dest", 1024*2);
        tfs.test();

合并文件

 //合并文件
    public void merge(String destPath) throws IOException {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
        for (int i= 0;  i< destPaths.size(); i++) {
            InputStream is = new BufferedInputStream(new FileInputStream(destPaths.get(i)));

            //拷贝
            byte[] flush = new byte[6];//缓冲容器
            int len = -1;//接收长度
            while ((len = is.read(flush))!=-1){
                os.write(flush,0,len);
            }
            os.flush();

            is.close();
        }
        os.close();
    }

调用

  TestFileSplit tfs = new TestFileSplit("src/SOA.txt", "src/dest", 1024);
        tfs.test();
        tfs.merge("copy-SOA.txt");

用序列流来合并

  public void merge2(String destPath) throws IOException {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
        Vector<InputStream> vi = new Vector<InputStream>();
        SequenceInputStream sis = null;
        for (int i= 0;  i< destPaths.size(); i++) {
           vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(i))));
            //拷贝
        }
        sis = new SequenceInputStream(vi.elements());
        byte[] flush = new byte[6];//缓冲容器
        int len = -1;//接收长度
        while ((len = sis.read(flush))!=-1){
            os.write(flush,0,len);
        }
        os.flush();
        sis.close();
        os.close();
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值