jboss学习 - vfs---转载
jboss的VFS是為了解決什么問題,他為什么有用呢
在jboss中有很多類似的資源操作的代碼都分散在程序的各個地方,大多數情況下代碼首先確定操作的資源的類型,比如是文件或者是文件夾,通過URL加載的資源等,在不同的代碼中其中包含了相同的代碼。
例如
??public static URL[] search(ClassLoader cl, String prefix, String suffix)
???throws IOException {
??Enumeration[] e = new Enumeration[] { cl.getResources(prefix),
????cl.getResources(prefix + "MANIFEST.MF") };
??Set all = new LinkedHashSet();
??URL url;
??URLConnection conn;
??JarFile jarFile;
??for (int i = 0, s = e.length; i < s; ++i) {
???while (e[i].hasMoreElements()) {
????url = (URL) e[i].nextElement();
????conn = url.openConnection();
????conn.setUseCaches(false);
????conn.setDefaultUseCaches(false);
????if (conn instanceof JarURLConnection) {
?????jarFile = ((JarURLConnection) conn).getJarFile();
????} else {
?????jarFile = getAlternativeJarFile(url);
????}
????if (jarFile != null) {
?????searchJar(cl, all, jarFile, prefix, suffix);
????} else {
?????boolean searchDone = searchDir(all, new File(URLDecoder
???????.decode(url.getFile(), "UTF-8")), suffix);
?????if (searchDone == false) {
??????searchFromURL(all, prefix, suffix, url);
?????}
????}
???}
??}
??return (URL[]) all.toArray(new URL[all.size()]);
?}
?private static boolean searchDir(Set result, File file, String suffix)
???throws IOException {
??if (file.exists() && file.isDirectory()) {
???File[] fc = file.listFiles();
???String path;
???for (int i = 0; i < fc.length; i++) {
????path = fc[i].getAbsolutePath();
????if (fc[i].isDirectory()) {
?????searchDir(result, fc[i], suffix);
????} else if (path.endsWith(suffix)) {
?????result.add(fc[i].toURL());
????}
???}
???return true;
??}
??return false;
?}
上面的代碼在多個地方都會包含這樣的代碼。各自進行文件的處理,但是這種方式有一個很大的問題,就是熱發布,需要將文件覆蓋已經發布鎖定的文件。為了解決文件鎖的問題,可能需要將操作文件的代碼進行集中處理,正式因為這個,VFS工程出現了。
?
VFS發布的API
VFS的基本使用包括二部分內容
- 簡單的資源導航
- 訪問者模式的API
綜上所屬,jdk自身提供的資源導航,需要判定文件的類型,操作比較繁瑣。在VFS中我們將所有的類型抽象為一個類型-VirtualFile
public final class VirtualFile implements Serializable{
??? /**
???? * Get the simple VF name (X.java)
???? *
???? * @return the simple file name
???? */
??? public String getName();
??? /**
???? * Get the simple VF name mapped to lowercase (x.java) (used by case-insensitive filesystems like ZIP).
???? *
???? * @return the lowercase simple file name
???? */
??? public String getLowerCaseName();
??? /**
???? * Get the absolute VFS full path name (/xxx/yyy/foo.ear/baz.jar/org/jboss/X.java)
???? *
???? * @return the VFS full path name
???? */
??? public String getPathName();
??? /**
???? * Get the path name relative to a parent virtual file.? If the given virtual file is not a parent of
???? * this virtual file, then an?{@code?IllegalArgumentException} is thrown.
???? *
???? * @param parent the parent virtual file
???? * @return the relative path name as a string
???? * @throws IllegalArgumentException if the given virtual file is not a parent of this virtual file
???? */
??? public String getPathNameRelativeTo(VirtualFile parent) throws IllegalArgumentException ;
??? /**
???? * Get the absolute VFS full path name. If this is a URL then directory entries will have a trailing slash.
???? *
???? * @param url whether or not this path is being used for a URL
???? *
???? * @return the VFS full path name
???? */
??? String getPathName(boolean url);
??? /**
???? * When the file was last modified
???? *
???? * @return the last modified time
???? */
??? public long getLastModified();
??? /**
???? * Get the size
???? *
???? * @return the size
???? */
??? public long getSize();
??? /**
???? * Tests whether the underlying implementation file still exists.
???? *
???? * @return true if the file exists, false otherwise.
???? */
??? public boolean exists();
????
??? /**
???? * Determines whether this virtual file represents a true root of a file system.
???? * On UNIX, there is only one root "/". Howevever, on Windows there are an infinite
???? * number of roots that correspond to drives, or UNC paths.
???? *?
???? * @return?{@code?true} if this represents a root.
???? */?
??? public boolean isRoot();
??? /**
???? * Determine whether the named virtual file is a plain file.
???? *
???? * @return?{@code?true} if it is a plain file,?{@code?false} otherwise
???? */
??? public boolean isFile();
??? /**
???? * Determine whether the named virtual file is a directory.
???? *
???? * @return?{@code?true} if it is a directory,?{@code?false} otherwise
???? */
??? public boolean isDirectory() ;
??? /**
???? * Access the file contents.
???? *
???? * @return an InputStream for the file contents.
???? *
???? * @throws IOException for any error accessing the file system
???? */
??? public InputStream openStream();
??? /**
???? * Delete this virtual file
???? *
???? * @return?{@code?true} if file was deleted
???? */
??? public boolean delete();
??? /**
???? * Get a physical file for this virtual file.? Depending on the underlying file system type, this may simply return
???? * an already-existing file; it may create a copy of a file; or it may reuse a preexisting copy of the file.
???? * Furthermore, the retured file may or may not have any relationship to other files from the same or any other
???? * virtual directory.
???? *
???? * @return the physical file
???? *
???? * @throws IOException if an I/O error occurs while producing the physical file
???? */
??? public File getPhysicalFile() ;
??? /**
???? * Get a?{@code?VirtualFile} which represents the parent of this instance.
???? *
???? * @return the parent or?{@code?null} if there is no parent
???? */
??? public VirtualFile getParent();
??? /**
???? * Get the children.? This is the combined list of real children within this directory, as well as virtual children
???? * created by submounts.
???? *
???? * @return the children
???? */
??? public List<VirtualFile> getChildren();
??? /**
???? * Visit the virtual file system
???? *
???? * @param visitor the visitor
???? *
???? * @throws IOException for any problem accessing the virtual file system
???? * @throws IllegalArgumentException if the visitor is null
???? * @throws IllegalStateException if the file is closed
???? */
??? public void visit(VirtualFileVisitor visitor) throws IOException;
......
}
?
?正與以前的對與只讀文件的操作,只需要添加一些選項區清楚或者刪除資源,有時候清楚或者刪除資源需要處理一些臨時文件,比如嵌套的jar等。
轉換jdk或者RUL資源到VirtualFile,虛擬文件需要一個root,VFS類知道如何根據一個URL取得虛擬文件
public class VFS
{
?/**
?* Get the virtual file system for a root uri
?*
?* @param rootURI the root URI
?* @return the virtual file system
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL is null
?*/
?static VFS getVFS(URI rootURI) throws IOException
?/**
?* Create new root
?*
?* @param rootURI the root url
?* @return the virtual file
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL
?*/
?static VirtualFile createNewRoot(URI rootURI) throws IOException
?/**
?* Get the root virtual file
?*
?* @param rootURI the root uri
?* @return the virtual file
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL is null
?*/
?static VirtualFile getRoot(URI rootURI) throws IOException
?/**
?* Get the virtual file system for a root url
?*
?* @param rootURL the root url
?* @return the virtual file system
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL is null
?*/
?static VFS getVFS(URL rootURL) throws IOException
?/**
?* Create new root
?*
?* @param rootURL the root url
?* @return the virtual file
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL
?*/
?static VirtualFile createNewRoot(URL rootURL) throws IOException
?/**
?* Get the root virtual file
?*
?* @param rootURL the root url
?* @return the virtual file
?* @throws IOException if there is a problem accessing the VFS
?* @throws IllegalArgumentException if the rootURL
?*/
?static VirtualFile getRoot(URL rootURL) throws IOException
?/**
?* Get the root file of this VFS
?*
?* @return the root
?* @throws IOException for any problem accessing the VFS
?*/
?VirtualFile getRoot() throws IOException
?}
注:
這部分代碼是老的vfs的代碼,在新的vfs代碼中,已經不再依靠URL,而是采用mount的方式,此處只是為了表明思路。
你可以采用不同的方式來取得VFS的實例,比如getVFS, createNewRoot and getRoot
由于VFS的新版本已經發生了變化,可以看新代碼,此處不再詳述。(由于此部分直接翻譯,后續可以考慮按照新的版本重新寫一份)
?
VFS架構
VFS的發布的API非常直觀,他的實現非常復雜,這里進行一下闡述
每次創建一個VFS實例,配套的實例化一個VFSContext,他是根據VFSContextFactory生成的,他會根據不同的協議映射不同的實現類,比如文件系統映射為FileSystemContextFactory,Zip文件映射為ZipEntryContextFactory。
另外每次VFS創建的時候,匹配的VirtualFileHandler也會被生成,他知道如何處理不同的類型的資源
?
到這里基本上可以了解vfs的原理,后面不再進行描述,下面會學習vfs3的代碼,查看新代碼的原理?
原文地址:http://netliving.iteye.com/blog/839938
轉載于:https://www.cnblogs.com/davidwang456/p/4027077.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的jboss学习 - vfs---转载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 漫谈设计模式--3分钟理解桥接模式:笔和
- 下一篇: UML解惑:图说UML中的六大关系--转