浅谈Java文件、IO流(三)

最后稍微说一下文件的分割与合并,重在思路!!!重在思路!!!重在思路!!!

文件分割与合并:RandomAccessFile   关注seek方法。

思路:

第一步:初始操作

0)确定文件的块数

1)确定每块大小   注意处理边界,最后一块

2)每块的名称    

第二步:
1)分割
   a)每一块的起始点、第几块、实际大小

   b)文件分割

代码:

1、简单版

 /**
     *
     * @param src
     * @param blocksize
     * @param dest
     */
    public static void split(String src,int blocksize,String dest) throws IOException {

        //源文件和目标文件
        File srcFile = new File(src);
        //确定分割块的数量
        long filelen = srcFile.length();//文件长度
        long destsize = blocksize*48;
        long num = (int)filelen/destsize;
        num = filelen%blocksize==0?num:num+1;//分割后的文件数目

        InputStream in = null;
        BufferedOutputStream bos = null;
        in =new BufferedInputStream(new FileInputStream(srcFile));

        byte[] bytes =new byte[12];
        int len =0;
        for (int i =0;i<num;i++){
            String destName = dest +File.separator+srcFile.getName()+i+".txt";
            bos=new BufferedOutputStream(new FileOutputStream(destName));
            int count =0;
            while (-1 !=(len=in.read(bytes))){
                System.out.println(new java.lang.String(bytes,0,len));
                bos.write(bytes,0,len);
                count+=len;
                if (count>=destsize){//最后一块处理
                    break;
                }
            }
            bos.flush();
        }
        bos.close();
        in.close();

    }

2、封装版

package com.zr.IO.others;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class SplitFile1 implements Serializable{
    //文件路径
    private  String filePath;

    //分割后的存放目录
    private String destBlockPath;
    //文件大小
    private long length;
    //每一块的大小
    private long size;
    //文件名
    private String fileName;
    //文件每一块的大小
    private long blocksize;
    //文件每一块的名称
    private List<String> blockPath;

    public SplitFile1() {
        blockPath = new ArrayList<String>();//初始化文件块的名称
    }

    public SplitFile1(String filePath,String destBlockPath) {
       this(filePath,1024,destBlockPath);
    }

    public SplitFile1(String filePath,long blocksize,String destBlockPath) {
        this();
        this.filePath = filePath;
        this.blocksize = blocksize;
        this.destBlockPath = destBlockPath;
        init();
    }

    //初始化操作,计算块数,确定文件名称
    private void init() {
        //分割文件数量
        File file = null;
        //判断文件是否可分割
        if(null == filePath ||!(file = new File(filePath)).exists()){
            return;
        }
        //文件名称
        this.fileName = file.getName();
        //计算块数 注意最后一块
         length = file.length();//文件实际大小
        //修正每一块的大小
        if(this.blocksize>length){
            this.blocksize = length;
        }
        size = (long) Math.ceil(length*1.0/this.blocksize);//计算文件的块数,取整

        //确定每块文件名称
        initPathName();
    }

    /**
     * 分割文件,分割文件存放目录
     * 起始位置
     * 每块大小
     * 第几块
     * @param
     */
    public void split() throws IOException {

        long beginPos =0;
        long actualblocksize = this.blocksize;//实际大小

        for (int i =0;i<size;i++){
            if(i==size-1){//考虑最后一块
                actualblocksize = this.length - beginPos;
            }
            splitdetail(i,beginPos,actualblocksize);
            beginPos+=actualblocksize;
        }
    }

    /**
     * 文件实际分割
     *
     * @param i 第几块
     * @param beginPos 起始点
     * @param actualblocksize 文件实际大小
     */
    public void splitdetail(int i, long beginPos, long actualblocksize) throws IOException {
        File file= new File(filePath);
        File dest = new File(this.blockPath.get(i));

        //选择流
        RandomAccessFile raf = null;
        BufferedOutputStream bos = null;
        raf= new RandomAccessFile(file,"r");
        bos = new BufferedOutputStream(new FileOutputStream(dest));

        //读取文件
        raf.seek(beginPos);
        //缓冲区
        byte[] bytes = new byte[1024];
        //读取长度
        int len =0;
        while (-1!=(len=raf.read(bytes))){
            int count =0;
            if(actualblocksize-len>=0){
                //写出文件
                bos.write(bytes,0,len);
                actualblocksize-=len;//剩余量
            }else{
                bos.write(bytes,0, (int) actualblocksize);
                break;
            }
            bos.flush();
        }
        bos.close();
        raf.close();
    }

    private void initPathName(){
        for(int i =0 ;i<this.size;i++){
            this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
        }
    }


    /**
     * 文件的合并
     * @param destPath
     */
    public void merge(String destPath) throws IOException {
        File dest = new File(destPath);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest,true));
        BufferedInputStream bis =null;
        for(int i =0;i<this.blockPath.size();i++){
            bis = new BufferedInputStream(new FileInputStream(this.blockPath.get(i)));
            System.out.println(this.blockPath.get(i));
            //缓冲区
            byte[] bytes = new byte[1024];
            //读取长度
            int len =0;
            while (-1!=(len =bis.read(bytes))){
                bos.write(bytes,0,len);

            }
            bos.flush();

        }
        bos.close();
        bis.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值