【Java】–文件上传/下载及存储案例

  • Post author:
  • Post category:java




一、前言

最近遇到一个需求,要求上传/下载文件并存储。在完成对应需求开发过程中,遇到一些思考性问题。

对于文件上传,平时遇到主要有这两种,一种是准备好的文件上传,另一种是一种网络地址url文件下载。同时,文件也有大小,如果是大型文件上传,可能网络传输耗时长并且中途中断等等问题。

整个案例有如下思考:


场景



(1)、网络文件url上传;

(2)、文件导入方式上传;


思考



(1)、对于大文件,如何上传?

(2)、上传的文件,如何去管理这个文件?例如文件类型、文件大小、多少页等等



1、解决思路


对于网络文件url,加载这个大文件,有什么方案?


目前流行的网上方案有:

(a)、分片下载文件,再进行合并,再做业务处理

(b)、将文件临时加载到磁盘,然后进行业务处理

—-(a)方法是每次建立连接,按照要求跳过某些字节,每个线程只获取需要的字节保存小文件到本地,然后主线程在拼接。



不足

:这里每个线程都去连接网络url,只获取需要的字节。每次连接url都是耗时。并不是理想中的,文件本身是支持分片下载,然后拼接。】


如何去管理这个文件?例如文件类型、文件大小、多少页等等


可以利用一些组件如itextpdf等对不同类型文件进行解析得到对应信息进行保存。


一个大文件如何进行搜索,搜索的内容怎么定位到那一页?


例如如果是pdf文件,利用itextpdf对Pdf文件进行分页,将stream转换为文字信息,这样文字信息存储到ES中,方便搜索。【

待代码实现中…


文件用什么中间件进行存储,方便下载?


这里计划用mongodb存储。


例如pdf/word等文件,能否进行搜索文本?


【该问题后续思考解决方案…】



二、文件上传/下载代码实现

pom.xml依赖

      <!--用于操作Office系列-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.8</version>
        </dependency>
        <!--用于操作Word-->
        <!-- https://mvnrepository.com/artifact/net.sf.jacob-project/jacob -->
        <dependency>
            <groupId>net.sf.jacob-project</groupId>
            <artifactId>jacob</artifactId>
            <version>1.14.3</version>
        </dependency>
        <!--用于操作PDF-->
        <!-- https://mvnrepository.com/artifact/com.lowagie/itext -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.2</version>
        </dependency>

properties文件配置,如果文件太大,通过导入方式,会提示报错,由于是Tomcat默认容量不足,所以这里可以现在200MB的文件。

#设置tomcat上传文件的大小
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=200MB



1、网络文件url上传



1.1、整体文件下载到服务本地临时目录

    @RequestMapping("/uploadFileUrl.do")
    @ResponseBody
    public Object uploadFileUrl(){
   
        String filePath = "https://*******/解决方法.pdf";
        String targetPath = this.getClass().getClassLoader().getResource("").getPath();
        targetPath = targetPath.substring(1);
        return operatorFileService.uploadFileUrl(filePath,targetPath,"解决方法.pdf");
    }
    public String uploadFileUrl(String url,String targetPath,String fileName) {
   
        long begin_time = new Date().getTime();

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
    //    headers.add("Authorization", "token");
        HttpEntity<Resource> httpEntity = new HttpEntity<>(headers);
        /**
         * 缺点:如果文件很大的话,下载会比较慢,如何多线程进行下载???
         * todo 思考
         */
        ResponseEntity<byte[]> byRes = restTemplate.exchange(url, HttpMethod.GET,httpEntity, byte[].class);
        //得到数组
        byte[] body =  byRes.getBody();
        String pathUrl = saveFileToPath(body,targetPath,fileName);
        long end_time = new Date().getTime();
        long seconds = (end_time - begin_time);
        log.info("uploadFileUrl seconds:{}",seconds);
        return pathUrl



版权声明:本文为xunmengyou1990原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。