大家好,我是吉森。我在头条持续分享一些开发技巧、经验和技术,如果你也热爱各种开发技术,欢迎关注我。
前面分两期介绍了Apache Commons工具包的一部分工具,今天继续介绍Apache Commons工具包中提高开发效率的一项利器:VFS。
VFS指虚拟文件系统,不要被这个名字唬住了,它其实就是操作各种来源的文件的一套统一的API。有了它,我们可以方便地操作本地文件、zip和jar等多种压缩包中的文件、http/ftp服务器上的文件、临时文件,甚至是内存中的文件。怎么样,是不是跃跃欲试了?
统一入口
VFS工具包中,统一操作各类文件系统的类是FileSystemManager,想要获取它的实例非常的简单:
FileSystemManager manager = VFS.getManager();
有时候,我们为了获取更多的功能,会把它转型成子类:
DefaultFileSystemManager manager = (DefaultFileSystemManager) VFS.getManager();
有了FileSystemManager的实例,我们就可以开始操作各类文件系统了。
示例代码
下面话不多说,让我们先看一些代码示例,来看一下它究竟是怎么操作各类文件系统的:
// 获取文件系统管理器,它是统一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);
进一步探讨
通过上述代码,我们可以看出这里面最重要的两个抽象接口是FileObject和FileContent。
FileObject用于遍历文件的内容或者结构,这些文件是有层次结构的,可以通过一个FileObject获取到上级/下级的FileObject进行进一步操作。FileObject可能是文件或文件夹。
FileContent代表文件的内容,可以通过getInputStream获取到输入流读取文件内容,通过getOutputStream获取到输出流向文件中写入内容或创建新文件/文件夹。文件同时可以有多个输入流。流用完之后不要忘记关闭哦~
敲黑板总结啦:
附:各类文件的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
引入Commons-VFS
org.apache.commons
commons-vfs2
2.8.0
com.jcraft
jsch
0.1.55
commons-httpclient
commons-httpclient
3.1
参考资料
Apache Commons官方网站
今天介绍的内容就到这里了,感谢观看。
什么,还没看够?关注我看更多技术干货~