• 作者:老汪软件
  • 发表时间:2023-12-30 14:00
  • 浏览量:

前言

不管是在项目中还是日常需求,我们总是有操作文件数据的需求,Java中操作文件不可避免就要使用File类,而中为我们提供了一个操作文件的接口,通过该接口我们可以获取用户上传的文件对象并写入文件系统中。

文章目录 一、File类

java.io.File是 Java 标准库中用于操作文件和目录路径的类。它提供了很多方法,用于创建、删除、重命名、判断文件是否存在、获取文件信息等操作。

获取文件信息

文件和目录操作

文件路径操作

文件过滤

二、接口

是 框架提供的一个接口,用于表示处理文件上传的对象。它通常用于处理/form-data类型的请求,例如处理文件上传的表单。首先我们依旧可以通过源码的学习来进一步了解这个接口。

2.1 源码和方法功能

public interface MultipartFile extends InputStreamSource {
    String getName();
    @Nullable
    String getOriginalFilename();
    @Nullable
    String getContentType();
    boolean isEmpty();
    long getSize();
    byte[] getBytes() throws IOException;
    InputStream getInputStream() throws IOException;
    default Resource getResource() {
        return new MultipartFileResource(this);
    }
    void transferTo(File dest) throws IOException, IllegalStateException;
    default void transferTo(Path dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
    }
}

2.2void (File dest)

前面我们已经介绍了该方法是中提供的将上传文件保存到指定的文件中的抽象方法,溯源源码我们可以看到这个接口方法被三个实现类实现了,分别是、 和。

中的方法体

我们可以看到中的方法体主要是通过检测传进来的文件是否可用、是否存在,并在检测完成就执行写入的操作

public void transferTo(File dest) throws IOException, IllegalStateException {
        if (!this.isAvailable()) {
            throw new IllegalStateException("File has already been moved - cannot be transferred again");
        } else if (dest.exists() && !dest.delete()) {
            throw new IOException("Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
        } else {
            try {
                this.fileItem.write(dest);
                LogFormatUtils.traceDebug(logger, (traceOn) -> {
                    String action = "transferred";
                    if (!this.fileItem.isInMemory()) {
                        action = this.isAvailable() ? "copied" : "moved";
                    }
                    return "Part '" + this.getName() + "',  filename '" + this.getOriginalFilename() + "'" + (traceOn ? ", stored " + this.getStorageDescription() : "") + ": " + action + " to [" + dest.getAbsolutePath() + "]";
                });
            } catch (FileUploadException var3) {
                throw new IllegalStateException(var3.getMessage(), var3);
            } catch (IOException | IllegalStateException var4) {
                throw var4;
            } catch (Exception var5) {
                throw new IOException("File transfer failed", var5);
            }
        }
    }

上面这段demo中可能对于this.()有疑问,我们知晓这里的this其实是该类的实例化对象,但是这里的this.()就是拿来判断目的文件是否可用,调用的就是类的内部方法,判断是否可用的条件就是该目标文件是否被加载进内存中!

彻底弄懂Java中的MultipartFile接口和File类

这里给出一个使用该方法的例子,需要注意的是这时候方法要求的是一个目标File对象,我们需要在调用该目标方法的时候就根据目标路径创建了目标的File对象。

// 获取上传文件的原始文件名
String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());
// 构建目标文件对象
File destFile = new File("/path/to/destination/directory", originalFilename);
try {
    // 将上传文件保存到目标文件
    file.transferTo(destFile);
    return "File uploaded successfully!";
} catch (IOException e) {
    e.printStackTrace();
    return "Failed to upload the file.";
}

实现类

而另一个实现类和的区别就在于使用直接上传文件的话可能会出现目录跳跃的问题,而不会,这是因为其对路劲分隔符了相关的限制,具体的部分大家可以看看这篇博客:而这个实现类就更简单了,做了简单的输入输出流的copy,这里就不再水字数了。

彻底弄懂Java中的MultipartFile接口和File类

2. void (Path dest)

该默认方法在实现类中被重写了,但主要的功能还是不变,就是将上传的文件写入到指定路径的Path对象中实现文件上传的功能。

这里给出使用的示例代码:

// 构建目标文件路径
String uploadDirectory = "/path/to/destination/directory";
String originalFilename = file.getOriginalFilename();
Path filePath = Paths.get(uploadDirectory, originalFilename);
try {
// 将上传文件保存到目标文件
    file.transferTo(filePath);
    return "File uploaded successfully!";
} catch (IOException e) {
    e.printStackTrace();
    return "Failed to upload the file.";
}

总结

这篇文章主要围绕接口和File类中相关方法的功能进行梳理,其中有关文件写入File对象和Path对象重点进行了剖析,而具体的有关文件管理的部分知识大家可以关注后续荔枝梳理的有关整合MinIO的博客和后续的博文输出。希望能帮助到有需要的小伙伴~~~

今朝已然成为过去,明日依然向往未来!我是荔枝,在技术成长之路上与您相伴~~~

如果博文对您有帮助的话,可以给荔枝一键三连嘿,您的支持和鼓励是荔枝最大的动力!

如果博文内容有误,也欢迎各位大佬在下方评论区批评指正!!!