多种文件上传方式的实现

文件的上传方式

一、Javaweb方式

  • 测试:8MB的文件,耗时64
  • Servlet+fileupload

导入依赖

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

核心代码

/**
 * Created by KingsLanding on 2022/10/4 13:24
 */
@Slf4j
@WebServlet(urlPatterns = "/FileServlet")
public class FileUploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // 上传配置
    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB
    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 检测是否为多媒体上传
        if (!ServletFileUpload.isMultipartContent(request)) {
            // 如果不是则停止
            PrintWriter writer = response.getWriter();
            writer.println("Error: 表单必须包含 enctype=multipart/form-data");
            writer.flush();
            return;
        }

        // 配置上传参数
        DiskFileItemFactory factory = new DiskFileItemFactory();

        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置最大文件上传值
        upload.setFileSizeMax(MAX_FILE_SIZE);
        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(MAX_REQUEST_SIZE);
        // 中文处理
        upload.setHeaderEncoding("UTF-8");

        // 这个路径相对当前应用的目录
        String uploadPath = request.getServletContext().getRealPath("/upload/") ;

        // 如果目录不存在则创建
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }

        try {
            // 解析请求的内容提取文件数据
            long start = System.currentTimeMillis();
            @SuppressWarnings("unchecked")
            List<FileItem> formItems = upload.parseRequest(request);

            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 处理不在表单中的字段
                    if (!item.isFormField()) {
                        String fileName = new File(item.getName()).getName();
                        String filePath = uploadPath + File.separator + fileName;
                        File storeFile = new File(filePath);
                        // 保存文件到硬盘
                        item.write(storeFile);
                        long end = System.currentTimeMillis();
                        log.info("总耗时:"+(end-start));//总耗时:64
                    }
                }
            }
        } catch (Exception ex) {
        }

        // 跳转
        response.sendRedirect("/index");
    }
}

二、Spring

1.基本流

  • 测试:8MB的文件,耗时22
/**
 * Created by KingsLanding on 2022/10/3 21:55
 */
@Slf4j
@Controller
public class FileUpload {

    @GetMapping("/index")
    public String testFormLayouts(){
        return "file";
    }

    @PostMapping("/FileUpload")
    public String testUpload(@RequestPart("photo") MultipartFile header,//处理单文件上传
                             HttpSession session) throws IOException {

        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取当前工程下photo目录的真实路径
        String photo = servletContext.getRealPath("/photo/");

        File file = new File(photo);
        if (!file.exists()){
            file.mkdir();
        }
        //最终路径
        String photoPath=photo+header.getOriginalFilename();

        //基本流
        FileOutputStream fis=null;
        try {
            fis = new FileOutputStream(new File(photoPath));
            long start = System.currentTimeMillis();
            if (!header.isEmpty()){
                byte[] bytes = header.getBytes();
                fis.write(bytes);
            }
            long end = System.currentTimeMillis();
            log.info("总耗时:"+(end-start));//总耗时:11
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis!=null){
                fis.close();
            }
        }

        log.info("上传的文件名:"+header.getOriginalFilename()+"存储位置:"+photoPath+"文件大小"+header.getSize());
        return "file";
    }
}

2.缓冲流

  • 测试:8MB的文件,耗时11
/**
 * Created by KingsLanding on 2022/10/5 20:07
 */
@Controller
@Slf4j
public class FileUploadBuffer {

    @PostMapping("/FileUploadBuffer")
    public String testUpload(@RequestPart("photo") MultipartFile header,//处理单文件上传
                             HttpSession session) throws IOException {

        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取当前工程下photo目录的真实路径
        String photo = servletContext.getRealPath("/photoBuffer/");

        File file = new File(photo);
        if (!file.exists()){
            file.mkdir();
        }

        String photoPath=photo+header.getOriginalFilename();

        //缓冲流处理
        FileOutputStream fis=null;
        BufferedOutputStream fos=null;
        try {
            fis = new FileOutputStream(new File(photoPath));
            fos = new BufferedOutputStream(fis);
            
            long startBf = System.currentTimeMillis();
            if (!header.isEmpty()){
                byte[] bytes = header.getBytes();
                fos.write(bytes);
            }
            long endBf = System.currentTimeMillis();
            log.info("总耗时"+(endBf-startBf));//总耗时11

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            if (fos!=null){
                fos.close();
            }
        }

        log.info("上传的文件名:"+header.getOriginalFilename()+"存储位置:"+photoPath+"文件大小"+header.getSize());
        return "file";
    }
}

3.getInputStream()

  • 测试:8MB的文件,耗时3873
/**
 * Created by KingsLanding on 2022/10/5 20:07
 */
@Controller
@Slf4j
public class FileUploadGetInputStream {
    @PostMapping("/FileUploadGetInputStream")
    public String testUpload(@RequestPart("photo") MultipartFile header,//处理单文件上传
                             HttpSession session) throws IOException {

        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取当前工程下photo目录的真实路径
        String photo = servletContext.getRealPath("/photoStream/");

        File file = new File(photo);
        if (!file.exists()){
            file.mkdir();
        }

        String photoPath=photo+header.getOriginalFilename();

        //getInputStream();
        FileOutputStream fis01=null;
        try {
            long start = System.currentTimeMillis();
            if (!header.isEmpty()){
                InputStream inputStream = header.getInputStream();
                File file01 = new File(photoPath);
                fis01 = new FileOutputStream(file01);
                byte[] bytes = new byte[10];
                int len;
                while ((len=inputStream.read(bytes)) != -1){
                    fis01.write(bytes,0,len);
                }
            }
            long end = System.currentTimeMillis();
            log.info("总耗时:"+(end-start));//总耗时:3873

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis01!=null){
                fis01.close();
            }
        }

        log.info("上传的文件名:"+header.getOriginalFilename()+"存储位置:"+photoPath+"文件大小"+header.getSize());
        return "file";
    }
}

4.transferTo

  • 测试:8MB的文件,耗时5
/**
 * Created by KingsLanding on 2022/10/5 20:08
 */
@Slf4j
@Controller
public class FileUploadTransferTo {
    @PostMapping("/FileUploadTransferTo")
    public String testUpload(@RequestPart("photo") MultipartFile header,//处理单文件上传
                             HttpSession session) throws IOException {

        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取当前工程下photo目录的真实路径
        String photo = servletContext.getRealPath("/photoTransferTo/");

        File file = new File(photo);
        if (!file.exists()){
            file.mkdir();
        }

        String photoPath=photo+header.getOriginalFilename();

        //transferTo
        if (!(header.isEmpty())){
            long start = System.currentTimeMillis();
            header.transferTo(new File(photoPath));
            long end = System.currentTimeMillis();
            log.info("耗时:"+(end-start));//耗时:5
        }

        log.info("上传的文件名:"+header.getOriginalFilename()+"存储位置:"+photoPath+"文件大小"+header.getSize());
        return "file";
    }
}

前端测试界面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
基本流的文件上传:
<form th:action="@{/FileUpload}" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="photo"/>
    <input type="submit" value="上传"/>
</form>
<br>
缓冲流的文件上传:
<form th:action="@{/FileUploadBuffer}" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="photo"/>
    <input type="submit" value="上传">
</form>
<br>
getInputStream文件上传:
<form th:action="@{/FileUploadGetInputStream}" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="photo"/>
    <input type="submit" value="上传">
</form>
<br>
transferTo文件上传:
<form th:action="@{/FileUploadTransferTo}" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="photo"/>
    <input type="submit" value="上传">
</form>
<br>
Servlet文件上传:
<form th:action="@{/FileServlet}" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="photo"/>
    <input type="submit" value="上传">
</form>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

King'sLanding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值