Apache Commons VFS:Java内存虚拟文件系统,屏蔽不同IO细节

发布于:2025-07-29 ⋅ 阅读:(31) ⋅ 点赞:(0)

一、写在前面

官方文档:https://commons.apache.org/proper/commons-vfs/api.html

参考资料:
https://zhuanlan.zhihu.com/p/377361630
https://blog.csdn.net/weixin_42116348/article/details/135360858

Apache Commons VFS的特点,它支持多种文件系统,例如本地文件、CIFS、FTP、FTPS、SFTP等等。它的使用方式很灵活,可以很容易地集成到你的Java项目中。而且,VFS还很关注性能和稳定性,这在处理大量文件或大型项目时尤为重要。

VFS提供了一个虚拟文件系统的概念,它允许应用程序访问文件和目录,而不必关心底层文件系统的具体实现。这意味着,无论文件是存储在本地文件系统、网络文件系统还是分布式文件系统上,应用程序都可以使用相同的方式来访问它们。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-vfs2</artifactId>
    <version>2.10.0</version>
</dependency>
<!--访问Sftp服务器文件时需要引入-->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
<!--访问Http服务器文件时需要引入-->
<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

二、使用

1、基本使用


import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.VFS;

public class Test {

    public static void main(String[] args) throws Exception {
        // 获取 FileSystemManager 实例有多种方法。
        // 最简单的方法是使用静态的 VFS.getManager() 方法,该方法返回默认的 Commons VFS 实现。
        FileSystemManager fsManager = VFS.getManager();
        // resolveFile() 方法通过名称定位一个文件
        FileObject jarFile = fsManager.resolveFile("jar:E:\\test\\commons-beanutils-core-1.8.3.jar");

        // 每个文件都由一个 FileObject 实例表示。
        // 使用这个接口,你可以创建或删除文件,列出其子文件,读取或写入其内容,等等。
        FileObject[] children = jarFile.getChildren();
        System.out.println("Children of " + jarFile.getName().getURI());
        for (int i = 0; i < children.length; i++) {
            System.out.println(children[i].getName().getBaseName());
        }

    }
}

// 获取文件系统管理器,它是统一API入口
final DefaultFileSystemManager manager = (DefaultFileSystemManager) VFS.getManager();
//        manager.addProvider("http", new HttpFileProvider());
//        manager.addProvider("sftp", new SftpFileProvider());

/* 1. 本地文件,必须是绝对路径 */
final FileObject fileObject = manager.resolveFile("file:///your/path/a.txt");
final FileContent content = fileObject.getContent();

// 读取文件中内容
final String s = content.getString("utf-8");
System.out.println("s = " + s);

// 向文件中写内容
try (OutputStream outputStream = content.getOutputStream(true)) {
    outputStream.write("abcdefg".getBytes());
}

/* 2. 压缩文件,支持zip、jar、tar、gzip和bzip2 */
final FileObject tarFileObject = manager.resolveFile("tar:///your/path/test.tar/!test/a.png");
final FileContent tarContent = tarFileObject.getContent();
content1.write(Files.newOutputStream(Paths.get("s.png")));

// 遍历压缩文件的下级文件
final FileObject tarFileObject2 = manager.resolveFile("tar:///your/path/test.tar");
final FileObject[] children = tarFileObject2.getChildren();
for (FileObject child : children) {
    System.out.println(child.getName());
}

/* 3. Http和Https,需要依赖于commons-httpclient */
final FileObject httpFileObject = manager.resolveFile("http://commons.apache.org/proper/commons-vfs/filesystems.html");
final String httpContent = httpFileObject.getContent().getString("utf-8");
System.out.println("httpContent = " + httpContent);

/* 4. Classpath,通常是项目编译生成的target文件夹,或者jar、war等安装包 */
final FileObject classpathFileObject = manager.resolveFile("res://web.properties");
final String string = classpathFileObject.getContent().getString("utf-8");
System.out.println("string = " + string);

/* 5. Ftp、Ftps、Sftp,需要依赖于com.jcraft.jsch*/
FileSystemOptions opts = new FileSystemOptions();
// 不严格检查连接的HostKey
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");

final FileObject sftpFileObject = manager.resolveFile("sftp://root:{74AF5548271EAAA71716A254F1C46F24}@XXX.XXX.XXX.XXX/ReadMe", opts);
final String sftpContent = sftpFileObject.getContent().getString("utf-8");
System.out.println("string = " + sftpContent);

2、从远程FTP服务器下载文件

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.UserAuthenticator;
import org.apache.commons.vfs2.auth.SimpleUserAuthenticator;
import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
import org.apache.commons.vfs2.VFS;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;

public class FtpDownloadExample {
    public static void downloadFile(String remoteFilePath, String localFilePath) {
        FileObject remoteFile = null;
        try {
            // 设置FTP登录信息
            UserAuthenticator auth = new SimpleUserAuthenticator("用户名", "密码", null);
            FileSystemOptions opts = new FileSystemOptions();
            DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);

            FileSystemManager fsManager = VFS.getManager();
            remoteFile = fsManager.resolveFile("ftp://ftp.example.com" + remoteFilePath, opts);

            // 执行下载操作
            try (InputStream in = remoteFile.getContent().getInputStream();
                 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(localFilePath))) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = in.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (remoteFile != null) {
                try {
                    remoteFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3、上传sftp文件

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.UserAuthenticator;
import org.apache.commons.vfs2.auth.SimpleUserAuthenticator;
import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
import org.apache.commons.vfs2.VFS;
import java.io.FileInputStream;
import java.io.BufferedInputStream;

public class SftpUploadExample {
    public static void uploadFile(String localFilePath, String remoteFilePath) {
        FileObject localFile = null;
        FileObject remoteFile = null;
        try {
            // 设置SFTP登录信息
            UserAuthenticator auth = new SimpleUserAuthenticator("用户名", "密码", null);
            FileSystemOptions opts = new FileSystemOptions();
            DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);

            FileSystemManager fsManager = VFS.getManager();
            localFile = fsManager.resolveFile("file://" + localFilePath);
            remoteFile = fsManager.resolveFile("sftp://sftp.example.com" + remoteFilePath, opts);

            // 执行上传操作
            try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(localFilePath))) {
                remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (localFile != null) {
                try {
                    localFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (remoteFile != null) {
                try {
                    remoteFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

附:各类文件的URI格式

1. 本地文件
[file://] 绝对路径
2. 压缩文件
zip:// 压缩文件URI[! 绝对路径]

jar:// 压缩文件URI[! 绝对路径]
tar:// 压缩文件URI[! 绝对路径]
tgz:// 压缩文件URI[! 绝对路径]
tbz2:// 压缩文件URI[! 绝对路径]
3. HTTP/HTTPS
http://[ 用户名[: 密码]@] 主机名或ip地址[: 端口][ 绝对路径]
https://[ 用户名[: 密码]@] 主机名或ip地址[: 端口][ 绝对路径]
4. FTP/FTPS/SFTP
ftp://[ 用户名[: 密码]@] 主机名或ip地址[: 端口][ 相对路径]
ftps://[ 用户名[: 密码]@] 主机名或ip地址[: 端口][ 绝对路径]
sftp://[ 用户名[: 密码]@] 主机名或ip地址[: 端口][ 相对路径]
5. Classpath
res://classpath相对路径/image.png

网站公告

今日签到

点亮在社区的每一天
去签到