虚拟文件
虚拟文件
虚拟文件系统 (Virtual File System:缩写为VFS) 中的文件称之为虚拟文件(VirtualFile:缩写为VF )
通常情况下,VF位于本地文件系统。但是,IntelliJ Platform对其进行了抽象,VF 也可以表示为jar包中的类,版本控制系统中的老版本文件等等。
VFS 级别仅处理二进制内容。 VirtualFile 的内容被视为字节流,编码和行分隔符等概念需要由更高的系统级别进行处理。
虚拟文件能干什么
通常用来进行文件操作,例如遍历文件系统,获取文件内容,重命名,移动,删除等。
使用 VfsUtilCore.iterateChildrenRecursively() 递归文件可以防止死循环。
如何得到虚拟文件
操作环境 | API |
---|---|
操作 Action | 获取当前文件: AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE) 获取多个文件:AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY) |
Document | FileDocumentManager.getFile() |
PSI File | PsiFile.getVirtualFile() (如果PSI文件只存在于内存中,会返回null) |
虚拟文件(Virtual File) | LocalFileSystem.findFileByIoFile() VirtualFileManager.findFileByNioPath()/refreshAndFindFileByNioPath() (2020.2+) |
虚拟文件从哪来
从项目根文件开始扫描文件来构建VFS。VFS通过刷新操作来检测文件系统中的新文件。可以使用VirtualFileManager.syncRefresh()/asyncRefresh() 或 VirtualFile.refresh() 方法来执行刷新操作。当文件系统监听器收到文件修改事件时也会进行刷新操作。
由外部工具通过IntelliJ Platform APIs 创建了新文件,如果要立即访问,可能需要先主动调用刷新操作。
虚拟文件能保存多久?
在IDE进程的整个生命周期中,硬盘上的文件被映射为VirtualFile 实例,可能有多个实例对应同一个文件(文件称之为UserDataHolder ),实例可以被垃圾回收。所有的实例共享同一份UserDataHolder,如果这个文件被删除了,VirtualFile 实例将失效(isValid()返回false),针对该VirtualFile的操作也会引起异常。
如何创建虚拟文件?
通常不能直接创建虚拟文件。可以通过PSI API或java.io.File 来创建文件,创建的文件会被映射成为虚拟文件。
如果需要通过 VFS 创建文件。可以使用VirtualFile.createChildData() 创建VirtualFile 实例,使用 VirtualFile.setBinaryContent() 方法写入内容。
如何订阅VFS文件修改事件
可以通过 虚拟文件系统事件 了解更多详情。
了解IntelliJ Platform 消息机制可以参考文档:消息基础架构
了解IntelliJ Platform 监听器可以参考文档:监听器
project.getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES,
new BulkFileListener() {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
// handle the events
}
});
从 2019.2 版本开始,支持非阻塞监听器:AsyncFileListener.
如何分析和操作虚拟文件
VfsUtil 和 VfsUtilCore 提供了方便的方法
VfsUtilCore.createCompactVirtualFileSet() 可以批量保存虚拟文件
ProjectLocator 可以查找包含某个虚拟文件的项目
如何继承VFS
如果需要VFS管理本地文件系统外的文件(例如,http文件),需要实现 VirtualFileSystem 类(很可能也需要实现 VirtualFile 类),在2019.2及以后版本里,需要在 plugin.xml 注册使用 com.intellij.virtualFileSystem 扩展点 进行注册,2019.2 之前的版本需要在 plugin.xml 注册为组件
如果在本地文件系统的操作过程中,需要执行某些逻辑(例如:开发版本控制系统时,需要重命名和移动操作),可以实现LocalFileOperationsHandler 并通过 LocalFileSystem.registerAuxiliaryFileOperationsHandler() 进行注册
VFS使用规范
查看虚拟文件系统 (Virtual File System)