zoukankan      html  css  js  c++  java
  • jboss学习

    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

  • 相关阅读:
    hdu2138(求素数)
    hdu2104
    poj1664(放苹果)
    数塔问题给你有哪些启示?
    汉诺塔问题(1)
    算法的力量(转李开复)
    最长子序列问题之系列一
    forward和redirect的区别
    group by 和having
    java中的多态三要素是什么?
  • 原文地址:https://www.cnblogs.com/davidwang456/p/4027077.html
Copyright © 2011-2022 走看看