一、写在前面
官方文档: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