JavaIO:RandomAccessFile类 完成文件分割

使用 RandomAccessFile 随机访问文件类以及面向对象封装的思想
完成对指定文件的分割

public class SplitFile {
    private File f;//待分割的文件
    private int blocksize;//指定分割大小
    private String destname;//分割后放置的文件夹名称
    private int size;//文件分割块数
    private  long len;//文件总长度

    public SplitFile(String fname, int blocksize, String destname) {//构造函数
        this.f = new File(fname);//传入需要操作的文件名
        this.blocksize = blocksize;//文件分割大小
        this.destname=destname;//分割后文件存储位置
        init();//初始化
    }
    public SplitFile(String fname,  String destname) {//重载构造函数,默认分割大小为1024字节
       this(fname,1024,destname);
    }


    private void init() {
        len = this.f.length();//得到文件长度
        size = (int) (Math.ceil(len * 1.0 / blocksize));//得到分割后每块文件大小
    }

    public void split() throws IOException {//分割函数
        int beginpos = 0;//起始位置
        int actualsize = 0;//实际读取长度
        for (int i = 0; i < size; i++) {
            beginpos = i * blocksize;//起始位置最开始为0,然后是分割大小的倍数。
            if (i == size - 1) {//如果是最后一块,考虑无法平均分割
               actualsize = (int) len % blocksize;//最后一次要获取的实际长度
            } else {
                actualsize = blocksize;//不是最后一次 每次读取指定长度
            }
            System.out.println(i + "-----" + beginpos + "--------" + actualsize);
            //打印第几块,该块起始位置,该块实际大小
            spiltdetail(beginpos, actualsize,i);//循环调用实际分割函数
        }
    }

    private void spiltdetail(int beginpos, int actualsize, int i) throws IOException {
    //实际分割函数,根据上面的函数计算得到的每块大小进行读取和写入
        RandomAccessFile raf = new RandomAccessFile(this.f, "r");//随机访问文件类:读取模式
        File ff=new File(destname);
        ff.mkdir();
        RandomAccessFile raf2=new RandomAccessFile(new File(destname+"/"+i+"copy.txt"),"rw");//读入新的文件内
        raf.seek(beginpos);//设定起始位置
        byte[] flush = new byte[1024];
        int flag;
        while ((flag = raf.read(flush)) != -1) {
            if (actualsize > flag) {//如果需要读取的长度大于本次缓冲数组读取的长度,则全部读取
                raf2.write(flush, 0, flush.length);
              //   System.out.println(new String(flush, 0, flush.length));
                actualsize = actualsize - flag;
            } else {//否则读取所需要的部分
                raf2.write(flush, 0, actualsize);
               //   System.out.println(new String(flush, 0, actualsize));
                break;
            }
        }
        raf2.close();
        raf.close();//关闭流,后开先关
    }


    public static void main(String[] args) throws IOException {
        SplitFile sf=new SplitFile("sc.jpg",1024,"dest");//测试用例,分别指定待分割文件名,分割大小,分割后文件放置的目录
          sf.split();
        System.out.println("split over");
    }
}

可以添加一个方法实现分割文件的合并:

public void merge(String dest2) throws IOException {
    OutputStream os=new BufferedOutputStream(new FileOutputStream(dest2,true));//一个输出流,append为true代表续写模式
    for(int i=0;i<size;i++){//创建多个输入流的个数与文件分割次数一致
        InputStream is=new BufferedInputStream(new FileInputStream(destname+"/"+i+"copy.txt"));
        byte[]flush=new byte[1024];//缓冲容器
        int flag;
        while((flag=is.read(flush))!=-1){
            os.write(flush,0,flag);
        }
        os.flush();
        is.close();
    }
    os.close();
}

当多个输入流进行操作的时候考虑使用序列流方法
步骤:创建vector容器,将多个输入流放入容器中,将容器传入序列流中

public void merge(String dest2) throws IOException {
    OutputStream os=new BufferedOutputStream(new FileOutputStream(dest2,true));
    Vector<InputStream> vi=new Vector<>();
    SequenceInputStream sis=null;//序列流,可以装多个流
    for(int i=0;i<size;i++){//建立输入流的个数与文件分割次数一致
        vi.add(new BufferedInputStream(new FileInputStream(destname+"/"+i+"copy.txt")));
    }
    sis=new SequenceInputStream(vi.elements());//Vector容器的elements功能是返回容器内组件的枚举

    byte[]flush=new byte[1024];//缓冲容器
    int flag;
    while((flag=sis.read(flush))!=-1){
        os.write(flush,0,flag);
    }

    os.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值