Java分割合并文件

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 1、实现一个文件分割器,把一个大文件分割成若干个小文件(可根据情况自行设计),
 * 分割后的文件扩展名为dat,文件名为:原文件名+原扩展名+编号+.data
 * 2、把分割后的文件再合并(文件还原)成完整文件,与源文件一致。
 */
public class FGutil {
    /**
     * 文件分割
     *
     * @param src      源文件路径
     * @param fileSize 分割后每个文件的大小,单位是MB
     * @param dest     目标文件路径
     */
    public static void split(String src, int fileSize, String dest) {
        System.out.println("分割开始。。。");
        if ("".equals(src) || src == null || fileSize == 0 || "".equals(dest) || dest == null) {
            System.out.println("分割失败");
        }
        //源文件
        File srcFile = new File(src);
        //源文件的大小
        long srcSize = srcFile.length();
        //目标文件的大小(分割后每个文件的大小)
        long destSize = 1024 * 1024 * fileSize;

        int number = (int) (srcSize / destSize);
        //分割后文件的数目
        number = srcSize % destSize == 0 ? number : number + 1;

        //源文件名
        String fileName = src.substring(src.lastIndexOf("\\"));

        //输入字节流
        InputStream in = null;
        //输入缓冲流
        BufferedInputStream bis = null;
        //每次读取文件的大小为1MB
        byte[] bytes = new byte[1024 * 1024];
        //每次读取的长度值
        int len = -1;
        try (ConsumeTime consumeTime = new ConsumeTime()) {
            in = new FileInputStream(srcFile);
            bis = new BufferedInputStream(in);
            for (int i = 0; i < number; i++) {

                String destName = dest + File.separator + fileName + "-" + (i + 1) + ".data";
                OutputStream out = new FileOutputStream(destName);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int count = 0;
                //把字节数据写入目标文件中
                while ((len = bis.read(bytes)) != -1) {
                    bos.write(bytes, 0, len);
                    count += len;
                    if (count >= destSize) {
                        break;
                    }
                }
                //刷新
                bos.flush();
                bos.close();
                out.close();
            }
            System.out.println("分割完成");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (bis != null) {
                    bis.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 文件合并
     * 注意:在拼接文件路劲时,一定不要忘记文件的跟路径,否则复制不成功
     *
     * @param destPath 目标目录
     * @param srcPaths 源文件目录
     */
    public static void merge(String destPath, String... srcPaths) {
        System.out.println("开始合并。。。");
        if (destPath == null || "".equals(destPath) || srcPaths == null) {
            System.out.println("合并失败");
        }
        for (String string : srcPaths) {
            if ("".equals(string) || string == null) {
                System.out.println("合并失败");
            }
        }
        //合并后的文件名
        String name = srcPaths[0].substring(srcPaths[0].lastIndexOf("\\"));
        String destName = name.substring(0, name.lastIndexOf("-"));
        //合并后的文件路径
        destPath = destPath + destName;
        //合并后的文件
        File destFile = new File(destPath);
        OutputStream out = null;
        BufferedOutputStream bos = null;
        try (ConsumeTime consumeTime = new ConsumeTime()) {
            out = new FileOutputStream(destFile);
            bos = new BufferedOutputStream(out);
            for (String src : srcPaths) {
                File srcFile = new File(src);
                InputStream in = new FileInputStream(srcFile);
                BufferedInputStream bis = new BufferedInputStream(in);
                byte[] bytes = new byte[1024 * 1024];
                int len = -1;
                while ((len = bis.read(bytes)) != -1) {
                    bos.write(bytes, 0, len);
                }
                bis.close();
                in.close();
            }
            System.out.println("合并结束");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (bos != null) {
                    bos.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        /**
         * 分割测试
         */
        //要分割的大文件
        String src = "E:\\Spire.Doc.jar";
        int fileSize = 5;
        //文件分割后保存的路径
        String dest = "E:\\fgtest";
        split(src, fileSize, dest);

        /**
         * 合并测试
         */
        //合并后文件的保存路径
        String destPath = "E:\\hbtest";
        //要合并的文件路径
        String[] srcPaths = {
                "E:\\fgtest\\Spire.Doc.jar-1.data",
                "E:\\fgtest\\Spire.Doc.jar-2.data",
                "E:\\fgtest\\Spire.Doc.jar-3.data",
                "E:\\fgtest\\Spire.Doc.jar-4.data",
                "E:\\fgtest\\Spire.Doc.jar-5.data",
                "E:\\fgtest\\Spire.Doc.jar-6.data"};
        merge(destPath, srcPaths);
    }

}

try(ConsumeTime consumeTime = new ConsumeTime()) 这种写法在是JDK1.7 引入了一个新的接口AutoCloseable, 通常它的实现类配合try{}使用,可在 IO 流的使用上,经常可以看到下面这种写法。我们这使用它打印耗时。

/**
 * @description:
 */
public class ConsumeTime implements AutoCloseable{
    private long start;

    public ConsumeTime(){
        this.start = System.currentTimeMillis();
    }

    @Override
    public void close() throws Exception {
        System.out.println("耗时: " + (System.currentTimeMillis() - start));
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值