Java SE | IO | 文件切割 文件合成

文件切割

1. 按文件大小切割

  • 步骤
  1. 创建字节流输入对象读取源文件
  2. 设置缓冲区大小(即要分割的独立文件大小)
  3. 创建字节流输出对象将缓冲区的数据写入到单个文件中
package demo1;

import java.io.*;

public class SplitFileTest {

private static final int BUFFER_SIZE = 1024*200;// 1024*1024
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    public static void main(String[] args) throws IOException {
        File srcFile = new File("D:\\code_test3\\Lighthouse.jpg");
        File partsDir = new File("D:\\code_test4");
        splitFile(srcFile, partsDir);
    }
    /**
     * 切割文件。
     */
    public static void splitFile(File srcFile, File partsDir)
            throws IOException {
        // 健壮性的判断。
        if (!(srcFile.exists() && srcFile.isFile())) {
            throw new RuntimeException("源文件不是正确的文件或者不存在");
        }
        if (!partsDir.exists()) {
            partsDir.mkdirs();
        }
        // 1,使用字节流读取流和源文件关联。
        FileInputStream fis = new FileInputStream(srcFile);
        // 2,明确目的。目的输出流有多个,只创建引用。
        FileOutputStream fos = null;
        // 3,定义缓冲区。1M.
        byte[] buf = new byte[BUFFER_SIZE];// 1M
        // 4,频繁读写操作。
        int len = 0;
        int count = 1;// 碎片文件的编号。
        while ((len = fis.read(buf)) != -1) {
            // 创建输出流对象。只要满足了缓冲区大小,碎片数据确定,直接往碎片文件中写数据 。
            // 碎片文件存储到partsDir中,名称为编号+part扩展名。
            fos = new FileOutputStream(new File(partsDir, (count++) + ".part"));
            // 将缓冲区中的数据写入到碎片文件中。
            fos.write(buf, 0, len);
            // 直接关闭输出流。
            fos.close();
        }
        /*
         * 将源文件以及切割的一些信息也保存起来随着碎片文件一起发送。
         */
        String filename = srcFile.getName();
        int partCount = count;
        // 创建一个输出流。
        fos = new FileOutputStream(new File(partsDir, count + ".properties"));
        fos.write(("filename=" + filename + LINE_SEPARATOR).getBytes());
        fos.write(("partCount=" + Integer.toString(partCount)).getBytes());
        fos.close();
        fis.close();
    }
}

  • 注意:该程序执行后会生成一个properties配置文件,配置文件中存放源文件的名称、后缀以及分割的文件个数。使用properties文件存放信息利于对文件的合并。

2. 按指定数量切割

文件合成

  • 对一个文件进行切割(一个源对应多个目的),切成碎片,在将碎片进行合并成原来的文件。
package demo1;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;

public class MergerFileTest3 {
    public static void main(String[] args) throws IOException{
        File partdir = new File("D:\\code_test4");
        mergerFile(partdir);
    }
    /**
     * 合并文件的方法
     */
    public static void mergerFile(File partsDir) throws IOException{
        File configFile = getConfigFile(partsDir);
        Properties prop = getProperties(configFile);
        merge(partsDir,prop);
    }
    /**
     * 获取配置文件
     * @return
     */
    public static Properties getProperties(File configFile) throws IOException {
        FileInputStream fis = null;
        Properties prop = new Properties();
        try {
            // 读取流和配置文件
            fis = new FileInputStream(configFile);
            prop.load(fis);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    System.err.println("err");
                }
            }
        }
        return prop;
    }
    /**
     * 根据目录获取配置文件对象
     */
    private static File getConfigFile(File dir) {
        if (!dir.exists() && dir.isDirectory()) {
            throw new RuntimeException("文件路径异常");
        }
        // 判断当前文件夹中是否存在碎片文件,使用文件过滤器
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".properties");
            }
        });
        if (files.length != 1) {
            throw new RuntimeException("配置文件不存在");
        }
        File congfigFile = files[0];
        return congfigFile;
    }
    /**
     * 获取属性中的信息
     */
    private static void merge (File dir , Properties prop) throws IOException{
        String filename = prop.getProperty("filename");
        int partCount = Integer.parseInt(prop.getProperty("partCount"));
        //使用io包中的SequenceInputStream,对碎片文件进行合并,将多个读取流合并成一个读取流。
        ArrayList<FileInputStream> list = new ArrayList<>();
        for (int i = 1; i < partCount; i++) {
            list.add(new FileInputStream(new File(dir,i +".part")));
        }
        // 获取枚举对象
        Enumeration<FileInputStream> en = Collections.enumeration(list);
        SequenceInputStream sis = new SequenceInputStream(en);
        FileOutputStream fos = new FileOutputStream(new File(dir, filename));
        // 读写
        byte[] buf = new byte[1024];
        int len;
        while ((len = sis.read()) != -1) {
            fos.write(buf,0,len);
        }
        fos.close();
        sis.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值