欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot实现文件的上传和下载

程序员文章站 2022-06-02 14:10:41
...

文件上传和下载

一、 前端file.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传</title>
</head>
<body>

<form action="/fileUpload" enctype="multipart/form-data" method="post">
       <input type="file" name="file"/>
       <input type="submit" value=”上传文件”>
</form>

<div>
    <a href="/download">点击下载</a>
</div>
</body>
</html>

multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,且不会对字符编码。

注意:
(1)在SpringMVC中,处理文件上传需要导入依赖包commons-io包:

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

使用依赖包commons-io的情形:

public String fileUpload(@RequestParam("file") CommonsMultipartFile
file) 

(2)SpringBoot 中处理文件上传使用默认的StandardServletMultipartResolver,相关的自动配置在MultipartAutoConfiguration之中。我们可以使用spring.servlet.multipart进行配置,当然也可以使用commons-io包,不过需要将默认的方法排除掉:

spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration

(3)我们这里直接采用的是MultipartFile接口方法
SpringBoot实现文件的上传和下载

CommonsMultipartFile 的常用方法:
String getOriginalFilename():获取上传文件的原名,如test.html
InputStream getInputStream():获取文件流
void transferTo(File dest)将上传文件保存到一个目录文件中

二、文件上传与下载:

  • 文件上传时需要定义上传文件的地址以及文件名,从file中获取字节流,输出到指定的文件路径中。
  • 文件下载时,获取下载文件的完整路径,推荐使用Buffer缓冲流的方式下载文件。
@RestController
public class TestController {

    @PostMapping("/fileUpload")
    public String fileUpload(HttpServletRequest req, HttpServletResponse resp,@RequestParam("file") MultipartFile file) {
        if(file.isEmpty()){
            return "未选择上传文件";
        }
        String originalFilename = file.getOriginalFilename();
        String path = "G:/glp/"+originalFilename;
        File dest = new File(path);
        if(!dest.getParentFile().exists()){
            dest.getParentFile().mkdir();
        }
        try{
            file.transferTo(dest);
            return "上传成功";
        }catch (IOException e){
            e.printStackTrace();
        }
        return "上传失败";
    }

    @GetMapping("/download")
    public String fileDownLoad(HttpServletRequest req,HttpServletResponse resp){
        File file = new File("G:/glp/高立鹏-19829497840-Java研发工程师.pdf");
        if(!file.exists()){
            return "下载文件不存在";
        }
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));){
            byte[] buff = new byte[1024];
            OutputStream outputStream = resp.getOutputStream();
            int len =0;
            while ((len=bis.read(buff))!=-1){
                outputStream.write(buff,0,len);
                outputStream.flush();
            }
        }catch (IOException e){
            e.printStackTrace();
            return "下载失败";
        }
        return "下载成功";
    }
}

注意:
这里采用了transferTo来上传文件。

三、BufferedInputStream

BufferedInputStream是一个带有缓冲区的输入流,通常使用它可以提高我们的读取效率,现在我们看下BufferedInputStream的实现原理:

  • BufferedInputStream内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快,所以BufferedInputStream的效率很高!
  • 不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!这就是inputstream与bufferedinputstream的区别.
  • BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式。
相关标签: JavaEE java