likes
comments
collection
share

上传文件功能

作者站长头像
站长
· 阅读数 16

引言

实现上传文件的功能,主要是需要处理和存储上传的文件。接口需要接收到Content-Typemultipart/form-data类型的file参数

实现一个文件上传的util方法,以供全局使用。下面将对此功能的实现进行一一讲解

功能逻辑分析

下面是实现上传文件所包含的主要步骤:

  1. 判断上传的文件是否为空;若为空,抛出错误异常
  2. 获取文件夹路径
  3. 判断放文件的文件夹是否存在;若不存在,创建文件夹
  4. 获取文件路径
  5. 判断上传的文件是否存在;若不存在,创建文件
  6. 将上传的文件内容保存到文件夹下的文件里

下面是其流程图,更加清晰的展示了此功能的流程逻辑: 上传文件功能

代码实现

public class UploadFileUtil {
    // 主流程代码
    public static String upload(MultipartFile file, String path, String directoryRootPath) throws IOException {
        assertFileIsEmpty(file);
        String directoryAbsolutePath = getAbsolutePath(directoryRootPath, "img");
        assertDirectory(directoryAbsolutePath);
        String fileName = getFileName(Objects.requireNonNull(file.getContentType()));
        String fileAbsolutePath = getAbsolutePath(directoryAbsolutePath, fileName);
        assertFile(fileAbsolutePath);
        saveFile(file, fileAbsolutePath);
        return path + fileName;
    }
    
    // 判断是否抛异常
    public static void assertIsError(boolean status, String message) {
        if (status) {
            throw new RuntimeException(message);
        }
    }

    // 判断文件是否为空
    public static void assertFileIsEmpty(MultipartFile file) {
        boolean isEmpty = file == null || file.isEmpty();
        assertIsError(isEmpty, "上传文件不能为空");
    }

    // 获取绝对路径公共方法
    public static String getAbsolutePath(String path, String name) {
        return path + "/" + name;
    }

    // 断言文件夹
    public static void assertDirectory(String path) {
        File directory = new File(path);
        if (!directory.exists()) {
            boolean success = directory.mkdir();
            assertIsError(!success, "文件夹创建失败");
        }
    }

    // 获取文件名字
    public static String getFileName(String contentType) {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        int beginIndex = contentType.indexOf("/") + 1;
        String type = contentType.substring(beginIndex);
        return uuid + "." + type;
    }

    // 断言文件
    public static void assertFile(String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            boolean success = file.createNewFile();
            assertIsError(!success, "文件创建失败");
        }
    }

    // 保存文件
    public static void saveFile(MultipartFile file, String path) throws IOException {
        File targetFile = new File(path);
        file.transferTo(targetFile);
    }
}

深入解析

MultipartFile

MultipartFileJava中用于处理通过HTTP请求上传的文件的类。它是Spring 框架的一部分,提供了各种方法来访问与上传文件相关的信息,如文件名、内容类型、大小等;它还提供了将上传的文件保存到本地磁盘的方法,以及读取上传文件的内容的方法

下面是MultipartFile类的一些常用方法:

  • getContentType():获取上传文件的MIME类型
  • isEmpty():判断上传文件是否为空
  • transferTo(File dest):将上传文件保存到本地磁盘上
  • getBytes():获取上传文件的字节数组
  • getInputStream():获取上传文件的输入流
  • getName():获取上传文件的名称
  • getOriginalFilename():获取上传文件的原始名称
  • getSize():获取上传文件的大小,单位为字节

File

FileJava中表示文件和目录路径名的类。它可以用于创建、删除、重命名、查询文件和目录等操作。File类的实例可以代表一个文件或目录,它并不代表文件的内容,只是表示文件或目录的路径名

下面是File类的一些常用方法:

  • exists():判断文件或目录是否存在
  • mkdir():创建一个新目录
  • createNewFile():创建一个新文件
  • getContentType:获取文件类型
  • getAbsolutePath():获取文件或目录的绝对路径
  • isDirectory():判断是否为目录
  • isFile():判断是否为普通文件
  • getName():获取文件或目录的名称
  • getPath():获取文件或目录的路径
  • getParent():获取文件或目录的父目录路径
  • length():获取文件的大小,单位为字节
  • delete():删除文件或目录
  • list():获取目录下的文件和目录列表
  • renameTo(File dest):重命名文件或目录

MultipartFile 和 File 异同

MultipartFileFile类虽然都是用于处理文件的类,但它们的功能和使用场景有所不同。MultipartFile适用于处理上传的文件,而File适用于处理本地文件和目录

MultipartFileFile
Spring框架中的一个接口Java 标准库中的一个类
处理HTTP multipart请求中上传的文件处理文件和目录路径名
处理上传的文件,即在请求中传递的文件处理本地文件,即存储在本地磁盘上的文件
提供了一些特定于上传文件的方法供了一些用于处理文件和目录的常规方法
上传的文件数据通常是存储在内存中或临时文件中处理的文件数据通常是存储在本地磁盘上
上传的文件数据可以是任意类型的二进制数据处理的文件数据通常是文本文件或二进制文件
  • MultipartFile提供特定于上传文件的方法,例如:getContentType()、getSize()、getOriginalFilename()等
  • File类提供用于处理文件和目录的常规方法,例如:exists()、isFile()、isDirectory()、delete()等

UUID

UUID(通用唯一标识符)是一种用于标识信息的标准化方法,可以在多个计算机系统中进行交互。它是由一个标识符的组合组成,该标识符保证在所有时间和空间中都是唯一的。UUID通常由32个十六进制数字(共128位)组成,它们可以根据不同的算法生成

Java中,可以使用java.util.UUID类来生成UUIDUUID类提供了两种类型的UUID基于时间戳的 UUID随机生成的 UUID

  • randomUUID():生成随机的UUID
  • fromTimeMillis():生成基于时间戳的UUID
  • toString():将UUID转换为字符串

由于UUID是唯一的,因此每次生成的UUID都是不同的。这使得它非常适合用作标识符,例如在数据库中存储记录时,可以使用UUID作为主键

基于时间戳的UUID是基于时间的,因此可能存在一个时间上限,在这个时间上限之后,生成的UUID可能会出现重复。而对于随机生成的UUID,由于其是随机生成的,因此重复的概率很小。无论使用哪种类型的UUID,都需要确保生成的UUID是唯一的