文件上传下载--基本概念

使用背景

?,当我打出问号的时候,不是你有问题,就是我有问题。文件的上传下载还需要问使用场景吗?虽然在开始写这篇文章的今天,我还在公司疑惑同事写的分片文件下载接口为什么返回值是void。
在大数据平台背景下,在进行数据湖开发时,需要用到将文件上传、文件下载的场景,当然,这是我在工作中碰到的。在其他项目中,对于文件的使用可能有更多的场景,尤其是一些办公系统,还有某些视频网站?

文件上传下载HTTP原理

文件上传时,HTTP主要需要对Content-type这个字段进行标识,其常用的有如下四个值:

  1. form-data
      http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition,用来说明字段的一些信息;由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。
  2. x-www-form-urlencoded
    就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=java&age = 23
  3. raw
      可以上传任意格式的文本,可以上传text、json、xml、html等
  4. binary
      相当于Content-Type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件,由于没有键值,所以,一次只能上传一个文件。如果想要同时传文件名,可以借用请求头“Content-Disposition”,设置文件名。
Content-Type: multipart/form-data; boundary=----

一般在进行文件上传时,多选择使用multipart/form-data来进行文件传输格式。在后端进行参数接收时,便于后端直接拿到文件的所有属性。

文件下载就相对简单些,一般在接口中,会直接的得到

//HttpServletResponse response;
response.addHeader("fileName", java.net.URLEncoder.encode(fileName, "UTF-8"));
//一些业务
//String mimeType = ContentInfoUtil.findExtensionMatch(fileName).getMimeType();
//response.setContentType(mimeType);

//写入响应头,该响应字段说明本次响应的值应该作为一个附件形式下载保存到本地
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
// 写文件输入流inputSteam到response中的输出流response.getOutputStream()

文件上传-MultipartFile

  • 拿到文件,调用接口:一些常见的参数肯定是需要自己制定的,业务参数这里也不例举了。一般的文件上传,在HTTP中,会将文件作为一个file类型的变量进行上传。
  • 在Java或者说Spring相关项目中,一般直接使用MultipartFile来进行对文件的接收,接收到了文件之后调用getOriginalFilename()方法获得文件名称,调用getInputStream()获得一个输入流,以便将文件通过输入流的形式将其存储到具体的文件服务器中。

文件下载-HttpServletResponse

  • 文件下载时,一般将其设置为附件,将其下载到本地,但是具体的传输还是需要依靠HTTP协议,在后台具体实现上,依靠HttpServletResponse中的outputSteam属性,将文件写入该属性中即可
            os = new BufferedOutputStream(response.getOutputStream());
            is = new BufferedInputStream(inputStream);
            is.skip(pos);
            byte[] buffer = new byte[1024];
            int lenght = 0;
            while (sum < rangeLenght) {
                lenght = is.read(buffer, 0, ((rangeLenght - sum) <= buffer.length ? ((int) (rangeLenght - sum)) : buffer.length));
                sum = sum + lenght;
                os.write(buffer, 0, lenght);
            }
  • 一般写入时都是依靠缓冲区的方式逐步写入

文件下载/上传优化

  • 分片上传/分片下载:当文件过大时,一次HTTP请求的负担过大,就可以考虑使用分片的方式进行文件上传或下载。具体逻辑:一般是先从后端获得一个分片标识id,之后一个文件的所有分片都使用这个id,每个分片都有文件信息,同时含有分片序号,以便后端将分片文件顺序拼接为一个文件。
posted @   jijdy  阅读(304)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示