文件上传与下载

文件上传

所谓文件上传,就是将本地文件(包括但不限于图片、音频、视频等)上传至服务器。

这里做一个简单的示例

前端注意事项及页面如下

1. 表单必须设置enctype="multipart/form-data" 

2. 提交方式必须是post,没有设置默认是get请求,会报错

3. 在file 类型的 input里设置的name属性值必须要和controller层接收的参数一致,否则要用  @RequestParam("和input里的name属性值一致")注解,不然会报错。

4. 如果是多文件上传,必须在文件输入框中设置 multiple=”multiple“ 属性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传与下载</title>
</head>
<body>
    <form method="post" enctype="multipart/form-data" action="/files/upload">
<!--        multiple="multiple"(可一次选择多个文件)-->
        <input type="file" name="files" multiple="multiple">
        <input type="submit" value="提交">

    </form>
</body>
</html>

后端部分

1. 在配置文件中设置文件上传的路径,便于后期维护,只需要找配置文件修改即可。我这里是application.yml文件,代码如下。

server:
  port: 8080

# 设置文件最终上传路径,后续只有在使用的地方用 @Value("${test/targetPath}") 注解即可 
test:
  targetPath: "Z:\\testUpload\\"

文件上传代码,主要是以下几个步骤

1. 判断接收的文件是否为空,若为空,可以根据实际情况给出提示。

2.  注入文件上传最终路径,并判断该文件夹是否存在,不存在则创建: mkdirs()。

3.  更换文件名,防止有上传至服务器有同名的文件。

4. 转存文件。


/**
 * 文件上传与下载
 * */

@Controller
@RequestMapping("/files")
public class FileController {

    // 代表上传文件的位置,把路径放在配置文件中便于后期维护
    @Value("${test.targetPath}")
    private String targetPath;


    @PostMapping("/upload")
    public void upload(@RequestParam("files") MultipartFile file) {
//  多文件上传
// public void upload(@RequestParam("files") MultipartFile[] file) {
        // 1. 判断文件是否上传
        if (file.isEmpty()) {
            //后续可以根据业务需求自行处理(抛出异常或提示等),这里简单演示
            System.out.println("文件为空");
        }

        // 2. 判断上传的目标目录是否存在,不存在则创建
        File f = new File(targetPath);
        if (!f.exists()) {  // 不存在创建文件夹
            f.mkdirs();
        }

        try {
            //3. 更换文件名称,防止文件名重复
            String fName = file.getOriginalFilename();
            // 得到文件名的后缀(.***)
            String suffix = fName.substring(fName.indexOf("."));
            String newName = UUID.randomUUID().toString() + suffix;
            //4. 把临时文件转储到目标文件夹中,因为程序执行完毕,临时文件就会销毁
            file.transferTo(new File(targetPath + newName));
            System.out.println("上传成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

至此文件上传功能就完成了。

文件下载

文件下载就是将服务器上的文件以IO流的形式写到本地计算机中。

前端页面就用一个<img />标签显示图片简单做下测试,name后面一串的假设就是服务器上要下载的文件名。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传与下载</title>
</head>
<body>
    <img src="/files/download?name=d6a63ffc-76a3-4931-bab8-6a3f90d443c5.JPG" alt="">
</body>
</html>

后端基本步骤

1. 在本地读取文件至程序中,需要定义一个字节输入流。

2. 定义一个字节输出流,将文件显示在浏览器中。

3. 读写文件。

4. 关闭流,先创建的流后关闭。

/**
 * 文件上传与下载
 * */

@Controller
@RequestMapping("/files")
public class FileController {

    // 代表上传文件的位置,把路径放在配置文件中便于后期维护
    @Value("${test.targetPath}")
    private String targetPath;


    @GetMapping("/download")
    public void download(String name, HttpServletResponse response) {  // name参数用于接收前端传递的文件名
    //如果下载的中文乱码,则需要指定编码格式
       response.setCharacterEncoding("UTF-8");
   // 设置下载后的文件名编码格式
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(传递过来的文件名, "UTF-8"));
        // 通过输入流读取文件内容
        try {
            FileInputStream inputStream = new FileInputStream(new File(targetPath + name));
            // 通过输出流,将文件写到浏览器中
            ServletOutputStream outputStream = response.getOutputStream();
            int len = 0;   // 记录每次读取文件的长度
            byte[] bytes = new byte[1024];  // 每次读取1kB文件大小
            while((len = inputStream.read(bytes)) != -1) {   // 读不到数据是返回-1
               /* // 最后一次从索引0开始读取,一直到len结束,否则最后一次读取不一定能装满1024个字节,如果没有装满,
                // 会造成最后一次读取的数据有上一次的数据没有覆盖*/
                outputStream.write(bytes, 0, len);
                outputStream.flush();  // 刷新流
            }
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }

}

结果

文件下载后乱码 

   //如果下载的中文乱码,则需要在读取文件时指定编码格式
    response.setCharacterEncoding("UTF-8");

   // 设置下载后的文件名编码格式

response.setHeader("Content-Disposition", "attrchment;filename=" + URLEncoder.encode(文件名, "UTF-8"));

文件下载打开的两种方式 

文件下载后打开有两种打开方式,第一种是在浏览器中打开,另一种是下载到本地计算机中打开。

1. 浏览器打开

浏览器打开是在浏览器中另开一个对话窗口,只需要在 a 链接中添加打开方式 target = "_blank"即可。同时在读取文件前设置文件编码格式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传与下载</title>
</head>
<body>
    <img src="/files/download?name=d6a63ffc-76a3-4931-bab8-6a3f90d443c5.JPG" target="_blank">
</body>
</html>

2. 下载到本地计算机打开

只需要在下载的 a 链接中添加 download 属性即可。需要注意的是,文件名有可能是中文的,因此在读取文件之前需要设置文件编码格式和文件名的编码格式。详情移步至本内容 “文件下载后乱码”章节。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传与下载</title>
</head>
<body>
    <img src="/files/download?name=d6a63ffc-76a3-4931-bab8-6a3f90d443c5.JPG" download="">
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值