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

jboss学习 - vfs---转载的更多相关文章

  1. Github上安卓榜排名第2的程序员教你如何学习【转载,侵删】

    来自:峰瑞资本(微信号:freesvc)文章作者:代码家(微信 ID:daimajia_share) 软件早已吞噬整个世界,程序员是关键角色.过去 40 年中,许多伟大的公司都由程序员缔造,比如比尔· ...

  2. Android之动画的学习(转载)

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  3. Redis学习手册——转载

    转载出处:http://www.cnblogs.com/stephen-liu74/archive/2012/04/16/2370212.html 为什么自己当初要选择Redis作为数据存储解决方案中 ...

  4. DIV+CSS系统学习:转载

    第一部分 HTML 第一章 职业规划和前景 职业方向规划定位: web前端开发工程师 web网站架构师 自己创业 转岗管理或其他 web前端开发的前景展望: 未来IT行业企业需求最多的人才 结合最新的 ...

  5. paper 53 :深度学习(转载)

    转载来源:http://blog.csdn.net/fengbingchun/article/details/50087005 这篇文章主要是为了对深度学习(DeepLearning)有个初步了解,算 ...

  6. Hadoop家族学习路线图--转载

    原文地址:http://blog.fens.me/hadoop-family-roadmap/ Sep 6, 2013 Tags: Hadoophadoop familyroadmap Comment ...

  7. [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)

    转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...

  8. Spring Boot 源码学习之转载

    这次的学习,主要转载了 波波老师的笔记,后续会自己整理一份 1.Spring-Boot源码分析-源码编译:https://dpb-bobokaoya-sm.blog.csdn.net/article/ ...

  9. git学习【转载】

    最近参与别人的github项目时,学习了Git的使用,首先需要在https://github.com/网站上注册账号和邮箱,然后fork一个开源项目,然后下载目前Windows下最新版本的git,下载 ...

随机推荐

  1. ORACLE调度之基于事件的调度(二)【weber出品】

    一.回顾 调度分基于时间的调度和基于事件的调度. 稍微复习一下前面的只是请浏览:<ORACLE调度之基于时间的调度(一)[weber出品]> 二.知识补充 1.队列:一种数据结构,就像一根 ...

  2. CRM窗体中只读的控件不会引发Update事件

    在CRM的窗体设计时,如果把某一个控件设为只读了,仅管你在后台用代码修改了值,这个值也不会起任何作用,更不会提交到后台,触发Update事件!

  3. js移动设备手机跳转地址代码

    if(/AppleWebKit.*mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alc ...

  4. thinkphp 内置函数详解

    D() 加载Model类M() 加载Model类 A() 加载Action类L() 获取语言定义C() 获取配置值    用法就是   C("这里填写在配置文件里数组的下标")S( ...

  5. win7 IIS7.0 【IIS 管理器无法验证此内置帐户是否有访问权】

    异常信息: 服务器配置为将传递身份验证和内置帐户一起使用,以访问指定的物理路径.但是,IIS 管理器无法验证此内置帐户是否有访问权.请确保应用程序池标识具有该物理路径的读取访问权.如果此服务器加入到域 ...

  6. centos和Ubuntu区别

    centos中新建的非root用户是没有sudo的权限的,如果需要使用sudo权限必须在/etc/sudoers 中加入账户和权限,所以切换到root账号的时候只需要输入:su,加入root账号的密码 ...

  7. ROS是Robot Operating System

    ROS是Robot Operating System 机器人操作系统ROS | 简介篇   同样,从个人微信公众号Nao(ID:qRobotics)搬运. 前言 先放一个ROS Industrial一 ...

  8. ARC下的内存泄露

    iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下面列举两种ARC导致内存泄露的情况. 1,循环参照 A有个属性参照B, ...

  9. SQLServer 取小时

    select datepart(hh,getdate())--orselect datename(hh,getdate())

  10. zoj 3785 What day is that day?

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5272 打表找规律. #include <cstdio> #incl ...