分片上传大文件

该博客介绍了如何使用Java处理大文件,通过分片将大文件拆分为多个小文件,然后进行合并。分片过程通过计算文件大小并逐块传输实现,而合并操作则按顺序读取并整合所有分片文件。此外,还提供了一个前端上传分片文件到后端并直接合并的API示例。
摘要由CSDN通过智能技术生成


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
 
public class FileSpiltAndMerge {
 
    public static void main(String[] args) throws IOException {
        spilt("D:\\file\\aaa.zip", 1, "D:\\file\\fenpian");
        merge("D:\\file\\fenpian", "D:\\file\\hebing.zip");
    }
 
    public static void spilt(String from, int size, String to) throws IOException {
        File f = new File(from);
        FileInputStream in = new FileInputStream(f);
        FileOutputStream out = null;
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = null;
 
        // 将MB单位转为为字节B
        long m = size * 1024 * 1024;
        // 计算最终会分成几个文件
        int count = (int) (f.length() / m);
        for (int i = 0; i <= count; i++) {
            // 生成文件的路径
            String t = to + "/" + i;
            try {
                out = new FileOutputStream(new File(t));
                outChannel = out.getChannel();
                // 从inChannel的m*i处,读取固定长度的数据,写入outChannel
                if (i != count)
                    inChannel.transferTo(m * i, m, outChannel);
                else// 最后一个文件,大小不固定,所以需要重新计算长度
                    inChannel.transferTo(m * i, f.length() - m * count, outChannel);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                out.close();
                outChannel.close();
            }
        }
        in.close();
        inChannel.close();
    }
 
    public static void merge(String from, String to) throws IOException {
        File t = new File(to);
        FileInputStream in = null;
        FileChannel inChannel = null;
 
        FileOutputStream out = new FileOutputStream(t, true);
        FileChannel outChannel = out.getChannel();
 
        File f = new File(from);
        // 获取目录下的每一个文件名,再将每个文件一次写入目标文件
        if (f.isDirectory()) {
            List<File> list = getAllFileAndSort(from);
            // 记录新文件最后一个数据的位置
            long start = 0;
            for (File file : list) {
 
                in = new FileInputStream(file);
                inChannel = in.getChannel();
 
                // 从inChannel中读取file.length()长度的数据,写入outChannel的start处
                outChannel.transferFrom(inChannel, start, file.length());
                start += file.length();
                in.close();
                inChannel.close();
            }
        }
        out.close();
        outChannel.close();
    }
    
    private static List<File> getAllFileAndSort(String dirPath) {
        File dirFile = new File(dirPath);
        File[] listFiles = dirFile.listFiles();
        List<File> list = Arrays.asList(listFiles);
        Collections.sort(list, (o1, o2) -> {
            return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
        });
        return list;
    }
}
 

如果因大文件请求超时前端进行分片的话后端直接保存分片文件,无需进行分片操作,只进行合并操作

//保存分片文件到指定路径
@PostMapping("/file/upload")
R fileUpload(@RequestParam("file") MultipartFile file,String fileName) {
        //文件保存路径
    String path = filePath+getUserId();
    File parentFileDir = new File(path);
        //如果无路径则创建
    if (!parentFileDir.exists()) {
        parentFileDir.mkdirs();
    }
    // 获取文件名(包括后缀)
    try (FileOutputStream fos = new FileOutputStream(path+"\\" + fileName)) {
        //写入文件
        fos.write(file.getBytes());
        return R.ok();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
    return R.error();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值