有兴趣的同学可以移步笔者的个人博客 更多博客
Apache VFS
简要介绍
VFS (虚拟文件系统),可以通过程序 去操作文件系统,这里说的文件系统是一个泛称,不同的文件系统有着不同的操作权限,它具体包括下表的几种文件系统(红色标记的是我们之后可能会用到的文件系统):
Name
Authentication
Read
Write
Create/Delete
Random
Version
Rename
FILE
NO
Yes
Yes
Yes
Read/Write
NO
Yes
FTP
Yes
Yes
Yes
Yes
Read
NO
Yes
HTTP
Yes
Yes
NO
NO
Read
NO
NO
BZIP2
NO
Yes
Yes
NO
NO
NO
NO
FTPS
Yes
Yes
Yes
Yes
Read
NO
Yes
GZIP
NO
Yes
Yes
NO
NO
NO
NO
HDFS
NO
Yes
NO
NO
Read
NO
NO
HTTPS
Yes
Yes
NO
NO
Read
NO
NO
Jar
NO
Yes
NO
NO
NO
NO
NO
RAM
NO
Yes
Yes
Yes
Read/Write
NO
Yes
RES
NO
Yes
Yes
Yes
Read/Write
NO
Yes
SFTP
Yes
Yes
Yes
Yes
Read
NO
Yes
Tar
NO
Yes
NO
NO
NO
NO
NO
Temp
NO
Yes
Yes
Yes
Read/Write
NO
Yes
WebDAV
Yes
Yes
Yes
Yes
Read/Write
Yes
Yes
Zip
NO
Yes
NO
NO
NO
NO
NO
VFS使得各种不同的文件系统使用一个API。例如本地磁盘上的文件,HTTP服务器上的文件或Zip存档内的文件。
开始使用
依赖
org.apache.commons
commons-vfs2
2.0
核心API
1.FileSystemManager
管理文件系统的接口,是最上层的接口,必须先得到FileSystemManager(在mybatis中类似于sqlSessionFactory),可以获得具体的FileObjectFileObject在下面会有介绍(获取sqlSession)。
获取FileSystemManager最常用的方式就是:
FileSystemManager fsm = VFS.getManager();
2.FileObject
它代表一个文件,和Java File不同,它具有更多延伸的功能和信息。实现FileObject接口的文件对象有很多大部分FileObject实现类都继承AbstractFileObject类,如下是常用的实现类:
LocalFile
FtpFileObject
HttpFileObject
SftpFileObject
ZipFileObject
TarFileObject
RamFileObject
UrlFileObject
/**
* @param path
* @return
*/
FileObject fileobject = fsm.resolveFile(path);
path是文件的路径,不同的文件系统有不同的前缀
File
[file://] absolute-path
Examples:
file:///home/someuser/somedir
file:///C:/Documents and Settings
file:/somehost/someshare/afile.txt
/home/someuser/somedir
c:\program files\some dir
c:/program files/some dir
Ftp
ftp://[ username[: password]@] hostname[: port][ relative-path]
Examples:
Http
FileObject表示一个具体文件,文件有两种类型:
目录
普通文件
普通文件拥有数据或者说内容。而目录不含有内容,只能包含其他文件。
FileObject提供大量的方法,足以满足读取,删除,复制,重命名等基本操作。
高级特性及demo
文件的监听
FileListener 有两个实现类DelegateFileObject和WeakRefFileListener,时间有限没有研究这两个实现类是干什么的,有兴趣的同学可以研究一下,但是这个监听类是可以绑定到文件系统上面的。
FileSystemManager fsm = VFS.getManager();
FileObject fileObject = fsm.resolveFile(path);
//在文件系统中添加监听器(lambda和匿名内部类都会方便点,也可以直接new个对象传到addListener方法中)
fileObject.getFileSystem().addListener(fileObject,new FileListener() {
@Override
public void fileCreated(FileChangeEvent fileChangeEvent) throws Exception {
String name = fileChangeEvent.getFile().getName().getBaseName();
System.out.print("文件创建了"+name);
}
@Override
public void fileDeleted(FileChangeEvent fileChangeEvent) throws Exception {
String name = fileChangeEvent.getFile().getName().getBaseName();
System.out.print("文件删除了"+name);
}
@Override
public void fileChanged(FileChangeEvent fileChangeEvent) throws Exception {
String name = fileChangeEvent.getFile().getName().getBaseName();
System.out.print("文件更改了"+name);
}
});
if (fileObject.exists()){
//删除path对应的文件或者目录
//fileObject.delete()
}else{
//创建一个文件
fileObject.createFile();
//或者创建文件夹
//fileObject.createFolder()
}
文件过滤
通过看API试出来的方法,这方面网上的资料太少了,只有以后遇到什么需求在查看API去解决。
FileSystemManager fsm = VFS.getManager();
FileObject fileObject = fsm.resolveFile(path);
//lambda表达式更加直观方便
FileSelector selector = new FileFilterSelector((fileSelectInfo)->{
boolean isCSV = fileSelectInfo.getFile().getName().getBaseName().endsWith(".txt");
return isCSV;
});
//匿名内部类,效果等同于上面的lambda
// FileSelector selector = new FileFilterSelector(new FileFilter() {
// @Override
// public boolean accept(FileSelectInfo fileSelectInfo) {
// boolean isCSV = fileSelectInfo.getFile().getName().getBaseName().endsWith(".txt");
// return isCSV;
// }
// });
FileObject[] findFiles = fileObject.findFiles(selector);
for (int i = 0; i < findFiles.length; i++) {
String name = findFiles[i].getName().getBaseName();
System.out.print(name);
}
}
这段代码的作用就是过滤出在path下*.txt的所有文件