目录
一、前言
最近遇到一个需求,要求上传/下载文件并存储。在完成对应需求开发过程中,遇到一些思考性问题。
对于文件上传,平时遇到主要有这两种,一种是准备好的文件上传,另一种是一种网络地址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