文件上传需要使用流,Spring为此准备了一个接口MultipartFile,其内维护了缓存流,并且具备自动开关流功能。

    简单文件上传实现案例基础步骤:
    1.获取文件名称
    2.准备上传文件的目录
    3.封装文件全路径 目录/文件名称
    4.实现文件上传

    简单示例代码:

    1. //1.获取文件名称
    2. String fileName = file.getOriginalFilename();
    3. //2.准备文件目录
    4. String fileDir = "E:/images/";
    5. //2.1判断文件目录是否存在
    6. File dir = new File(fileDir);
    7. if (!dir.exists()) {
    8. dir.mkdirs();//创建多级目录
    9. }
    10. //3.封装文件全路径
    11. String localPath = fileDir + fileName;
    12. //4.实现文件上传
    13. file.transferTo(new File(localPath));

    实现文件校验:
    步骤如下:

    1. 校验文件是否为图片

      若要校验一个文件是否为常用图片需要使用正则表达式 首先获取文件名称,需要使用MultipartFile接口提供的getOriginalFilename()方法。 String fileName = file.getOriginalFilename(); 另外由于windows大小写不敏感需要将文件名转换为全小写,方便使用正则表达式校验 fileName = fileName.toLowerCase(); 使用正则表达式动态的匹配文件后缀名

    1. if (!fileName.matches("^.+\\.(jpg|png|gif)$")) {
    2. return null;
    3. }
    1. 判断文件是否满足图片固有属性,而不是1.exe.jpg等文件

    使用图片的IO流来获取图片的宽度与高度,根据文件是否有宽度和高度来判断是否为图片
    使用图片的字节输入流来获取文件宽度高度,其参数为字符输入流,再使用getWidth();getHeight();方法获取图片属性进行判断

    1. BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
    2. int width = bufferedImage.getWidth();
    3. int height = bufferedImage.getHeight();
    4. if (width == 0 || height == 0) {
    5. return null;
    6. }
    1. 将文件名分目录处理
      1. 3.1将文件按照后缀名分配,效率提升不能满足要求
      2. 京文件按照上传日期分配 yyyy/MM/dd/HH 可以
      3. 根据商品分类进行分配,由分布不均现象
      4. 根据名称hash 之后截串,弊端hash码可能出现分布不均现象。

    使用日期格式化方法将日期按照年月日进行格式化,然后与文件上传后的路径进行拼接,若该文件不存在,将会创建文件夹。

    1. String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
    2. String localDirPath = localDir + dateDir;
    3. File dirFile = new File(localDirPath);
    4. if (!dirFile.exists()) {
    5. dirFile.mkdirs();
    6. }
    1. 使用uuid替换文件名防止重名

    使用字符串的lastIndexOf();方法获取文件名的最后一个“.”的位置方便截取文件类型,
    获取到文件类型后,使用uuid将文件名进行替换,替换完毕后与文件类型进行拼接,组成完整的文件名

    1. String uuid = UUID.randomUUID().toString().replace("-", "");
    2. //截取文件后缀
    3. int index = fileName.lastIndexOf(".");
    4. String fileType = fileName.substring(index);
    5. String newFileName = uuid + fileType;

    完整代码实现:

    1. package com.jt.service.impl;
    2. import com.jt.service.FileService;
    3. import com.jt.vo.ImageVO;
    4. import org.springframework.stereotype.Service;
    5. import org.springframework.web.multipart.MultipartFile;
    6. import javax.imageio.ImageIO;
    7. import java.awt.image.BufferedImage;
    8. import java.io.File;
    9. import java.io.IOException;
    10. import java.text.SimpleDateFormat;
    11. import java.util.Date;
    12. import java.util.UUID;
    13. @Service
    14. public class FileServiceImpl implements FileService {
    15. private String localDir = "E:/images";
    16. @Override
    17. public ImageVO upload(MultipartFile file) {
    18. String fileName = file.getOriginalFilename();
    19. //windows大小写不敏感,将文件后缀名字母转换为全小写
    20. fileName = fileName.toLowerCase();
    21. if (!fileName.matches("^.+\\.(jpg|png|gif)$")) {
    22. return null;
    23. }
    24. try {
    25. BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
    26. int width = bufferedImage.getWidth();
    27. int height = bufferedImage.getHeight();
    28. if (width == 0 || height == 0) {
    29. return null;
    30. }
    31. //根据时间进行目录创建
    32. String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
    33. String localDirPath = localDir + dateDir;
    34. File dirFile = new File(localDirPath);
    35. if (!dirFile.exists()) {
    36. dirFile.mkdirs();
    37. }
    38. //uuid的唯一只是系统内部唯一
    39. String uuid = UUID.randomUUID().toString().replace("-", "");
    40. //截取文件后缀
    41. int index = fileName.lastIndexOf(".");
    42. String fileType = fileName.substring(index);
    43. String newFileName = uuid + fileType;
    44. //实现文件上传
    45. String realFilePath = localDirPath + newFileName;
    46. file.transferTo(new File(realFilePath));
    47. //6.封装返回值
    48. /*
    49. 6.1封装虚拟路径,在各个系统中灵活切换,只保存动态变化的路径
    50. path = 时间/uuid.type
    51. */
    52. String virtualPath = dateDir + newFileName;
    53. String url = "https://img.alicdn.com/tfs/TB1FjZ7VWL7gK0jSZFBXXXZZpXa-520-280.png";
    54. return new ImageVO(virtualPath, url, newFileName);
    55. } catch (IOException e) {
    56. e.printStackTrace();
    57. return null;
    58. }
    59. }
    60. }