1.输入流input:读取外部数据(硬盘、光盘等储存设备的数据)到内存(也就是程序)中;
2.输出output:将程序(内存)的数据输出到硬盘等储存设备中;
其实文件下载和上传可以这样理解:上传:从本地上传到网络,只需要一步;
而下载,首先得从网络上下载(也就是从外部数据:硬盘..上下载到内存,利用输入流InputStream),然后再保存到本地(意思就是保存到本地这个硬盘上,利用输出流OutputStream),这是两步;
文件下载:
思路:1、设置路径,若文件存在,响应头设置contentType("application/force-download")设置强制下载。addHeader("Content-Disposition","attachment","fileName"+文件名)设置文件名作为请求头;
2、然后定义输入输出流,输出流负责将程序中的数据(也就是网页中拥有的数据)输出到硬盘中,输入流负责将硬盘也就是外部储存的文件进行读取:
@RequestMapping("/download")public void download(String path, HttpServletResponse response) { try { // path是指想要下载的文件的路径 File file = new File(path); log.info(file.getPath()); // 获取文件名 String filename = file.getName(); // 获取文件后缀名 String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(); log.info("文件后缀名:" + ext); // 将文件写入输入流 FileInputStream fileInputStream = new FileInputStream(file); InputStream fis = new BufferedInputStream(fileInputStream); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.setCharacterEncoding("UTF-8"); //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存 //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3" // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称 response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); // 告知浏览器文件的大小 response.addHeader("Content-Length", "" + file.length()); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); outputStream.write(buffer); outputStream.flush(); } catch (IOException ex) { ex.printStackTrace(); }}
第二种方法-文件上传:
1.首先来看MultipartAutoConfiguration自动配置类中绑定配置属性的类:
@ConfigurationProperties( prefix = "spring.servlet.multipart", ignoreUnknownFields = false)public class MultipartProperties { private boolean enabled = true; private String location; private DataSize maxFileSize = DataSize.ofMegabytes(1L); private DataSize maxRequestSize = DataSize.ofMegabytes(10L); private DataSize fileSizeThreshold = DataSize.ofBytes(0L); private boolean resolveLazily = false; public MultipartProperties() { }
2.然后我们可以在application.properties中对文件上传的一些配置进行自定义设置:
spring.servlet.multipart.max-file-size=10MBspring.servlet.multipart.max-request-size=100MBspring.servlet.multipart.enabled=true
3.然后我们写控制器,利用控制器来完成文件上传操作(当用户在客户端请求文件上传时,控制器对此进行处理)
@Controller@Slf4jpublic class PracticeController { @PostMapping("/upload1") public String upload(@RequestParam("email")String email, @RequestParam("username") String username, @RequestPart("headerImg") MultipartFile headerImg, @RequestPart("photos") MultipartFile[] photos) throws IOException {//提示信息 System.out.println("单文件上传信息为:"+headerImg.getOriginalFilename()); System.out.println("多文件上传个数为:"+photos.length); for (MultipartFile photo : photos) { System.out.println("多文件信息为:"+photo.getOriginalFilename()+",文件大小:"+photo.getSize()/1000+"kb"); }// 将文件上传到指定文件夹,利用transferTo():复制到 if(!headerImg.isEmpty()){ //得到文件名字 String filename = headerImg.getOriginalFilename(); headerImg.transferTo(new File("E:\"+filename)); } // 多文件 if(photos.length>0){ for (MultipartFile photo : photos) { //将每个文件一一上传 photo.transferTo(new File("E:\"+photo.getOriginalFilename())); } } return "成功"; }}