美文网首页
虚拟文件系统

虚拟文件系统

作者: pr488 | 来源:发表于2017-01-13 23:08 被阅读108次

    原文链接:
    http://www.jetbrains.org/intellij/sdk/docs/basics/virtual_file_system.html

    虚拟文件系统(VFS)是IntelliJ平台 的一个组件,它封装了处理文件的大部分操作。它主要有以下几个目的:

    • 提供一个处理文件的通用API,而不用管文件的真实位置(磁盘上、归档中或HTTP服务器上);
    • 跟踪文件修改,并在检测到修改时提供文件内容的旧版本和新版本;
    • 提供将其它持久性数据与VFS中的文件关联的可能性。

    为了提供后两个特性,VFS管理用户硬盘的某些内容的持久性快照。 快照仅存储那些至少被VFS API请求一次的文件,并且异步更新匹配磁盘上发生的更改。

    快照是应用级,而不是项目级的。因此,即使多个项目引用了某些文件(例如,JDK中的类),VFS也只会存储一个副本。

    所有VFS的访问操作都通过快照。

    如果通过VFS API请求的某些信息的快照不可用,则将从磁盘加载它并将其存储到快照中。 如果信息在快照中可用,则返回快照数据。 只有访问了特定信息,目录中的文件内容和文件列表才会存储在快照中 - 否则只会存储名称,长度,时间戳等属性的文件元数据。

    注意 这意味着文件系统的状态和IntelliJ Platform UI中显示的来自快照的文件内容并不总是匹配磁盘的实际内容。

    例如在某些情况下,IntelliJ平台外部删除的文件在UI中仍然可以显示一段时间。

    快照在刷新操作 期间从磁盘更新,这通常是异步的。 所有通过VFS进行的写操作都是同步的——即内容立即保存到磁盘。

    刷新操作使VFS的一部分状态与实际磁盘的内容同步。 刷新操作由* IntelliJ平台 *或插件代码显式调用,即当IDE运行时在磁盘上的文件更改时,VFS不会立即更新。 VFS将在下一次刷新操作后更新文件。

    IntelliJ平台 会在启动时异步刷新整个项目内容。默认情况下,用户从其它应用切换到IDE时会执行刷新操作,但是用户可以通过设置|外观和行为|系统设置|框架或选项卡激活时同步文件关闭它

    在Windows,Mac和Linux系统中,IntelliJ平台 会启动一个本地文件监控进程接受文件系统的更改通知。如果文件监控可用,刷新操作将只更新更改的文件,否则将遍历所有文件夹中文件。

    刷新操作基于文件时间戳。 如果文件的内容已更改,但其时间戳保持不变,* IntelliJ平台 *不会接收更新的内容。

    目前没有从快照中删除文件的功能。 如果文件被加载一次,它将永远保留在那里,除非它从磁盘中删除,并且在其一个父目录上调用了刷新操作。

    VFS本身不支持忽略设置|文件类型|文件中列出的文件和排除项目结构|模块|源代码|排除中的文件夹。 如果应用代码访问它们,VFS将加载并返回其内容。 在大多数情况下,忽略的文件和排除的文件夹必须从较高级别代码的处理中跳过。

    在IntelliJ平台IDE的运行实例的生命周期中,多个VirtualFile实例可能对应于同一个磁盘文件。 它们是相等的,有相同的hashCode并且共享用户数据。

    同步和异步刷新

    从调用者的角度来看,刷新操作可以是同步或异步的。 实际上,刷新操作根据它们自己的线程策略来执行,同步意味着调用线程将被阻塞,直到刷新操作(其很可能在不同的线程上运行)完成。

    同步和异步刷新都可以从任何线程启动。 如果从后台线程启动刷新,则调用线程必须不能保持读取操作,否则会发生死锁。更多线程模型和读写操作的信息请查阅通用线程规则

    相同的线程要求也适用于像LocalFileSystem.refreshAndFindFileByPath()这样的函数,如果在快照中找不到指定路径的文件,则执行部分刷新。

    几乎所有情况下都强烈建议使用异步刷新。 如果有一些代码需要在刷新完成后执行,代码应该作为postRunnable参数传递给以下刷新方法:

    在某些情况下,同步刷新可能会导致死锁,具体取决于调用刷新操作的线程有哪些锁。

    虚拟文件系统事件

    虚拟文件系统中发生的所有更改(由于刷新操作或由用户操作引起)都为虚拟文件系统事件。 VFS事件总是在事件分派线程和写入操作中触发。

    监听VFS事件的最有效的方法是实现BulkFileListener接口并订阅它到VirtualFileManager

    这个API使你可以检测到在刷新操作期间一个列表中的所有更改,并且可以批量处理它们。 你也可以实现VirtualFileListener接口并使用VirtualFileManager.addVirtualFileListener()注册它,这将允许您逐个处理事件。

    注意:VFS监听器是应用级的,它会将接收所有用户打开项目中发生的更改事件。 你可能需要过滤掉与你的任务无关的事件。

    VFS事件会在每次更改前后发送,你可以在before事件之前访问文件的旧内容。注意,刷新引起的事件会在磁盘内容更改之后发送——因此,当你处理beforeFileDeletion事件时,例如该文件已从磁盘中删除。 但是,它仍然存在于VFS快照中,你可以使用VFS API访问其最后的内容。

    注意:请注意,刷新操作仅针对已加载进快照中文件更改触发事件。 例如,如果你访问一个VirtualFile的目录,但从未使用VirtualFile.getChildren()加载其内容,当在该目录中创建文件时,可能不会收到fileCreated通知。

    如果使用VirtualFile.findChild()加载目录中的一个文件,你将收到该文件的更改通知,但是你可能无法收到同一目录中其它文件的创建/删除通知。

    相关文章

      网友评论

          本文标题:虚拟文件系统

          本文链接:https://www.haomeiwen.com/subject/densbttx.html