使用 RandomAccessFile 流分割与合并文件

长路漫漫,装X作伴

学习的时候写了下面这段代码:

import java.io.*;
import java.util.*;
/**
 * 文件分割与合并
 * Object Oriented Programming(OOP)
 */
public class SplitMergeFile {
    //源头
    private File src;
    //目的地(文件夹)
    private String destDir;
    //所有分割后的文件存储路径
    private List<String> destPaths;
    //每块的大小
    private int blockLen;
    //总共多少块
    private int size;
    
    public SplitMergeFile(String srcPath, String destDir, int blockLen) {
        this.src = new File(srcPath);
        this.destDir = destDir;
        this.blockLen = blockLen;
        this.destPaths = new ArrayList<String>();
        //初始化
        init();
    }
    
    //很鸡肋的初始化
    private void init() {
        long fileLen = this.src.length();
        this.size = (int) Math.ceil(fileLen * 1.0 / this.blockLen);
        for (int i = 0; i < this.size; i++) {
            this.destPaths.add(this.destDir + i + "_" + this.src.getName());
        }
    }
    
    /**
     * 分割文件
     * 1、计算每一块的起始位置和大小
     * 2、分割
     */
    public void splitFile() {
        long fileLen = this.src.length();
        int beginPos = 0;
        int actualLen = (int) (this.blockLen > fileLen ? fileLen : this.blockLen);
        for (int i = 0; i < this.size; i++) {
            beginPos = i * this.blockLen;
            if (i == this.size - 1) {
                actualLen = (int) fileLen;
            } else {
                actualLen = this.blockLen;
                fileLen -= actualLen;
            }
            splitBlock(i, beginPos, actualLen);
        }
    }
    
    private void splitBlock(int i, int beginPos, int actualLen) {
        RandomAccessFile rafr = null;
        RandomAccessFile rafrw = null;
        try {
            rafr = new RandomAccessFile(this.src, "r");
            rafrw = new RandomAccessFile(this.destPaths.get(i), "rw");
            rafr.seek(beginPos);
            byte[] flushBuffer = new byte[1024];
            int readLen = -1;
            while ((readLen = rafr.read(flushBuffer)) != -1) {
                if (actualLen > readLen) {
                    rafrw.write(flushBuffer, 0, readLen);
                    actualLen -= readLen;
                } else {
                    rafrw.write(flushBuffer, 0, actualLen);
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (rafr != null) {
                try {
                    rafr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (rafrw != null) {
                try {
                    rafrw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     * 文件的合并
     * destPath:目标路径+文件名
     */
    public void mergeFile(String destPath) {
        OutputStream os = null;
        SequenceInputStream sis = null; //序列流
        Vector<InputStream> vi = new Vector<InputStream>(); //流容器,这里Vector实现了List接口,所以此容器是有序的
        try {
            //输出流初始化
            os = new BufferedOutputStream(new FileOutputStream(destPath, true));
            //输入流初始化
            for (int i = 0; i < this.destPaths.size(); i++) {
                vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(i))));
            }
            sis = new SequenceInputStream(vi.elements()); //vi.elements()获取容器的迭代对象并传入序列流构造器参数
            //读取后写出
            byte[] flushBuffer = new byte[1024];
            int readLen = -1;
            while ((readLen = sis.read(flushBuffer)) != -1) { //sis.read()会通过迭代器依次调用容器里每一个输入流对象的read()方法
                os.write(flushBuffer, 0, readLen);
            }
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (sis != null) {
                try {
                    sis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void main(String[] args) {
        SplitMergeFile smf = new SplitMergeFile("D:/Images/volatileAtomicity.jpg", "D:/Images/raf_split/", 1024 * 20);
        smf.splitFile();
        smf.mergeFile("D:/Images/raf_split/mergeVolatileAtomicity.jpg");
    }
}

一段可以分割和合并文件的小程序有什么用?此时应该发挥自己荒唐的想象力,也许后面真的可以搞些有趣的事情。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容