JAVA实现大文件的分割

目标

文件太大不利用进行传输,实现将大文件分割小文件的工具类

开发环境

  •   语言: java 1.8
  •  操作系统 : windows 7
  •  开发工具: idea

代码


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *  将大文件分割为小文件
 * @author 2689592940@qqcom
 * @date 2020/10/10 10:46
 */
public class FileSlice {

    private static String FILE_PART_EXT = ".parts";

    /**
     * 分割文件
     *
     * @param file          文件
     * @param filePieceSize 每个文件大小
     *
     * @return 文件输出路径
     */
    public static String slice(File file, int filePieceSize) {
        if (!file.isFile()) {
            return null;
        }
        /**
         *  默认64M
         */
        if (filePieceSize == -1) {
            filePieceSize = 1024 * 1024 * 64;
        }
        /**
         * 计算要分割多少个文件
         */
        int howManyParts = calcParts(file.length(), filePieceSize);

        /**
         * 转换成流
         */
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);

            /**
             * 获取保存文件路径,不存在则创建
             */
            String[] split = file.getName().split("\\.");
            String oPath = file.getParent() + "\\" + file.getName() + "_" + System.currentTimeMillis();
            if (!(new File(oPath).exists())) {
                new File(oPath).mkdirs();
            }
            /**
             * 循环读取内容,分配到不同的区间
             */
            int len = -1;
            // 计算文件的hash
            String ext = split[split.length - 1];
            // 定义每次读取的字节数
            byte[] buffer = new byte[1024];

            for (int i = 1; i <= howManyParts; i++) {
                System.out.println("开始第" + i + "次的内容分配");
                int total = 0;
                // 生成的文件名
                String fileName = oPath + "\\" + file.getName() + "_" + i + "." + ext + FILE_PART_EXT;
                FileOutputStream fos = new FileOutputStream(fileName);
                while ((len = inputStream.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                    total += len;
                    if (total == filePieceSize) {
                        break;
                    }
                }
                fos.close();
            }
            return oPath;

        } catch (IOException e) {
            System.out.println("文件流读取失败: " + e.getMessage());
            return null;
        } finally {
            if (inputStream != null) {
                /**
                 * 关闭流
                 */
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 计算要分割多少个文件
     *
     * @param length        文件大小
     * @param filePieceSize 每个文件的大小
     *
     * @return int 分为多少块
     */
    private static int calcParts(double length, int filePieceSize) {
        return (int) Math.ceil(length / (double) filePieceSize);
    }

    /**
     * 将分割好的文件重新链接
     *
     * @param filePath 被分割好的其中之一文件路径,默认其他块与其在同一目录下
     *
     * @return 成功返回True,出错则返回False
     */
    public static String glue(String filePath) {
        File files = new File(filePath);
        File[] tempList = files.listFiles((dir, name) -> name.endsWith(FILE_PART_EXT));
        if (tempList.length == 0) {
            return null;
        }

        try {
            // 输出文件保存路径
            String combineFilePath = filePath + "/0/";
            File outPutFile = new File(combineFilePath);
            if (!outPutFile.exists()) {
                outPutFile.mkdirs();
            }
            // 获取
            int lastIndexOf = filePath.lastIndexOf("_");
            String combineFileName = combineFilePath + filePath.substring(filePath.lastIndexOf("\\") + 1, lastIndexOf);
            FileOutputStream fos = new FileOutputStream(combineFileName);

            byte[] buffer = new byte[1024];
            for (int i = 0; i < tempList.length; i++) {
                File file = tempList[i];
                int len = -1;
                FileInputStream inputStream = new FileInputStream(file);
                while ((len = inputStream.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                }
                inputStream.close();
            }
            fos.close();
            return combineFileName;
        } catch (IOException e) {
            System.out.println("文件流读取失败: " + e.getMessage());
            return null;
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        String filepath = "D:/书籍/test.txt";
        // String filepath = "D:/书籍/test.txt";
        // System.out.println(FileSlice.slice(new File(filepath), 64 * 1024 * 1024));
        System.out.println((new FileInputStream(new File(filepath))));
        String path = "D:\\书籍\\test.txt_1602318746849";
        System.out.println(FileSlice.glue(path));
    }
}

 思考

 - 分割文件可使用多线程 ? 速度是否会有提升

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值