有興趣的同學可以移步筆者的個人博客 更多博客
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存檔內的文件。
開始使用
依賴
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.0</version>
</dependency>
核心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
http://[ username[: password]@] hostname[: port][ absolute-path]
Examples:
http://127.0.0.1:8080/downloads/somefile.jar
http://[email protected]/index.html
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的所有文件