Java はローカル サーバーへの大きなファイル フラグメントのアップロードを実装します

コントローラ

    @PostMapping("/uploadShardingFileLocal")
    public AjaxResult uploadChunk(TchunkInfo chunk) {
    
    
        chunk.setSliceNo(chunk.getSliceNo()+1);
        MultipartFile file = chunk.getFile();
        String filePath = RuoYiConfig.getUploadPath();
        try
        {
    
    
            byte[] bytes = file.getBytes();
            Path path = Paths.get(FileInfoUtils.generatePath(filePath, chunk));
            //文件写入指定路径
            Files.write(path, bytes);
            //判断如果当前块数等于总块数 合并
            if (chunk.getSliceNo().equals(chunk.getFileSlicesNum()))
            {
    
    
                String taskId = chunk.getTaskId();
                //文件地址
                String localFile = filePath + "/" + taskId + "/" + chunk.getFileName();
                String folder = filePath + "/" + taskId;
                //合并文件
                FileInfoUtils.merge(localFile, folder, chunk.getFileName());
                int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
                String currentDir = StringUtils.substring(filePath, dirLastIndex);
                Map<String,String> resultMap = new HashMap<>();
                resultMap.put("fileUrl", serverConfig.getUrl() + Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + taskId + "/" + chunk.getFileName());
                resultMap.put("fileName", chunk.getFileName());
                return AjaxResult.success(resultMap);
            }
        } catch (IOException e)
        {
    
    
            e.printStackTrace();
            return AjaxResult.error("上传失败!");
        }
        return AjaxResult.success();
    }

ファイル情報ユーティリティ

package com.ruoyi.api.common.fileupload;

import com.ruoyi.common.core.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.*;

/**
 * 功能描述: 文件工具
 * @author zhang pu
 * @date 17:03 2023/8/1
 */
public class FileInfoUtils {
    
    

    private final static Logger logger = LoggerFactory.getLogger(FileInfoUtils.class);

    /**
     * 功能描述: 生成路径
     * @author zhang pu
     * @date 13:43 2023/7/31
     */
    public static String generatePath(String uploadFolder, TchunkInfo chunk) {
    
    
        StringBuilder sb = new StringBuilder();
        sb.append(uploadFolder).append("/").append(chunk.getTaskId());
        //判断uploadFolder/taskId 路径是否存在,不存在则创建
        if (!Files.isWritable(Paths.get(sb.toString())))
        {
    
    
            logger.info("path not exist,create path: {}", sb.toString());
            try
            {
    
    
                Files.createDirectories(Paths.get(sb.toString()));
            } catch (IOException e)
            {
    
    
                logger.error(e.getMessage(), e);
            }
        }
        return sb.append("/").append(chunk.getFileName()).append("-").append(chunk.getSliceNo()).toString();
    }

    /**
     * 文件合并
     *
     * @param file
     * @param folder
     * @param filename
     */
    public static AjaxResult merge(String file, String folder, String filename) {
    
    
        try
        {
    
    
            //先判断文件是否存在
            if (fileExists(file))
            {
    
    
                return AjaxResult.warn("文件已存在!");
            } else
            {
    
    
                //不存在的话,进行合并
                Files.createFile(Paths.get(file));
                Files.list(Paths.get(folder)).filter(path -> !path.getFileName().toString().equals(filename)).sorted((o1, o2) -> {
    
    
                    String p1 = o1.getFileName().toString();
                    String p2 = o2.getFileName().toString();
                    int i1 = p1.lastIndexOf("-");
                    int i2 = p2.lastIndexOf("-");
                    return Integer.valueOf(p2.substring(i2)).compareTo(Integer.valueOf(p1.substring(i1)));
                }).forEach(path -> {
    
    
                    try
                    {
    
    
                        //以追加的形式写入文件
                        Files.write(Paths.get(file), Files.readAllBytes(path), StandardOpenOption.APPEND);
                        //合并后删除该块
                        Files.delete(path);
                    } catch (IOException e)
                    {
    
    
                        logger.error(e.getMessage(), e);
                    }
                });
            }
        } catch (IOException e)
        {
    
    
            logger.error(e.getMessage(), e);
            //合并失败
            return AjaxResult.warn("合并失败!");
        }
        return AjaxResult.success();
    }

    /**
     * 根据文件的全路径名判断文件是否存在
     *
     * @param file
     * @return
     */
    public static boolean fileExists(String file) {
    
    
        boolean fileExists = false;
        Path path = Paths.get(file);
        fileExists = Files.exists(path, new LinkOption[]{
    
    LinkOption.NOFOLLOW_LINKS});
        return fileExists;
    }
}

チャンク情報

package com.ruoyi.api.common.fileupload;

import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;

public class TchunkInfo implements Serializable {
    
    

	private static final long serialVersionUID = 1L;

	/**
	 * 任务id 必传
	 */
	private String taskId;
    /**
     * 当前文件块,从1开始
     */
    private Integer sliceNo;
    /**
     * 每块大小
     */
    private Long chunkSize;
    /**
     * 总大小
     */
    private Long totalSize;
    /**
     * 文件名 必传
     */
    private String fileName;
    /**
     * 总块数  必传
     */
    private Integer fileSlicesNum;
    /**
     * 文件类型
     */
    private String type;
    /**
     * 块内容  必传
     */
    private transient MultipartFile file;


	public Integer getSliceNo() {
    
    
		return sliceNo;
	}

	public void setSliceNo(Integer sliceNo) {
    
    
		this.sliceNo = sliceNo;
	}

	public Long getChunkSize() {
    
    
		return chunkSize;
	}

	public void setChunkSize(Long chunkSize) {
    
    
		this.chunkSize = chunkSize;
	}

	public Long getTotalSize() {
    
    
		return totalSize;
	}

	public void setTotalSize(Long totalSize) {
    
    
		this.totalSize = totalSize;
	}

	public String getFileName() {
    
    
		return fileName;
	}

	public void setFileName(String fileName) {
    
    
		this.fileName = fileName;
	}

	public Integer getFileSlicesNum() {
    
    
		return fileSlicesNum;
	}

	public void setFileSlicesNum(Integer fileSlicesNum) {
    
    
		this.fileSlicesNum = fileSlicesNum;
	}

	public String getType() {
    
    
		return type;
	}

	public void setType(String type) {
    
    
		this.type = type;
	}

	public MultipartFile getFile() {
    
    
		return file;
	}

	public void setFile(MultipartFile file) {
    
    
		this.file = file;
	}

	public String getTaskId() {
    
    
		return taskId;
	}

	public void setTaskId(String taskId) {
    
    
		this.taskId = taskId;
	}
}

おすすめ

転載: blog.csdn.net/weixin_42456784/article/details/132046441