- Virtual Files
- How do I get a virtual file?
- What can I do with it?
- Where does it come from?
- How long does a virtual file persist?
- How do I create a virtual file?
- How do I get notified when VFS changes?
- Are there any utilities for analyzing and manipulating virtual files?
- How do I extend VFS?
- What are the rules for working with VFS?
- Java virtual file object
- Field Summary
- Method Summary
- Field Detail
- CLASS_VERSION
- Method Detail
- getInputStream
- getOutputStream
- getChild
- getChild
- toString
- getName
- getVirtualPath
- getFileSystem
- getPath
- getAbsolutePath
- getCanonicalPath
- getParent
- getParentFile
- Class File
- Interoperability with java.nio.file package
Virtual Files
A VirtualFile (VF) is the IntelliJ Platform’s representation of a file in a Virtual File System (VFS).
Most commonly, a virtual file is a file in a local file system. However, the IntelliJ Platform supports multiple pluggable file system implementations, so virtual files can also represent classes in a JAR file, old revisions of files loaded from a version control repository, and so on.
The VFS level deals only with binary content. Contents of a VirtualFile are treated as a stream of bytes, but concepts like encodings and line separators are handled on higher system levels.
How do I get a virtual file?
PsiFile.getVirtualFile() (may return null if the PSI file exists only in memory)
What can I do with it?
Typical file operations are available, such as traverse the file system, get file contents, rename, move, or delete. Recursive iteration should be performed using VfsUtilCore.iterateChildrenRecursively() to prevent endless loops caused by recursive symlinks.
Where does it come from?
The VFS is built incrementally by scanning the file system up and down, starting from the project root. VFS refresh operations detect new files appearing in the file system. A refresh operation can be initiated programmatically using VirtualFileManager.syncRefresh() / asyncRefresh() or VirtualFile.refresh() . VFS refreshes are also triggered whenever file system watchers receive file system change notifications.
Invoking a VFS refresh might be necessary for accessing a file that has just been created by an external tool through the IntelliJ Platform APIs.
How long does a virtual file persist?
A particular file on disk is represented by equal VirtualFile instances for the IDE process’s entire lifetime. There may be several instances corresponding to the same file, and they can be garbage-collected. The file is a UserDataHolder , and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid ( isValid() returns false ), and operations cause exceptions.
How do I create a virtual file?
Usually, you don’t. As a general rule, files are created either through the PSI API or through the regular java.io.File API.
If one needs to create a file through VFS, use VirtualFile.createChildData() to create a VirtualFile instance and VirtualFile.setBinaryContent() to write some data to the file.
How do I get notified when VFS changes?
Implement BulkFileListener and subscribe to the message bus topic VirtualFileManager.VFS_CHANGES . For example:
For a non-blocking alternative, starting with version 2019.2 of the platform, see AsyncFileListener .
Are there any utilities for analyzing and manipulating virtual files?
VfsUtil and VfsUtilCore provide utility methods for analyzing files in the Virtual File System.
For storing a large set of Virtual Files, use dedicated VfsUtilCore.createCompactVirtualFileSet() .
Use ProjectLocator to find the projects that contain a given virtual file.
How do I extend VFS?
To provide an alternative file system implementation (for example, an FTP file system), implement the VirtualFileSystem class (most likely you’ll also need to implement VirtualFile ), and register your implementation via com.intellij.virtualFileSystem extension point (2019.2 and later) or application component for earlier versions.
To hook into operations performed in the local file system (for example, when developing a version control system integration that needs custom rename/move handling), implement LocalFileOperationsHandler and register it via LocalFileSystem.registerAuxiliaryFileOperationsHandler() .
What are the rules for working with VFS?
See Virtual File System for a detailed description of the VFS architecture and usage guidelines.
Java virtual file object
Abstraction of an entry in some VirtualFileSystem. It could be a wrapper around a java.io.File, or a java.util.zip.ZipEntry, or whatever file-like element is managed by that layer.
Field Summary
Method Summary
Returns the VirtualFile representing the parent directory of this VirtualFile object, or null if this is the root file of the VirtualFileSystem.
Returns whether the case for the file on the file system is different than the case of the name used to obtain the file.
Returns a list of the files in the directory specified by this File that satisfy the specified filter.
Creates a directory whose pathname is specified by this File object, including any necessary parent directories.
Field Detail
CLASS_VERSION
static final java.lang.String CLASS_VERSION
Method Detail
getInputStream
java.io.InputStream getInputStream() throws java.io.IOException
getOutputStream
java.io.OutputStream getOutputStream() throws java.io.IOException
getChild
VirtualFile getChild(java.lang.String name)
getChild
VirtualFile getChild(atg.vfs.VirtualPath path)
toString
getName
Returns the name of the file represented by this object. The name is everything in the pathame after the last occurrence of the separator character.
getVirtualPath
atg.vfs.VirtualPath getVirtualPath()
getFileSystem
getPath
getAbsolutePath
java.lang.String getAbsolutePath()
getCanonicalPath
java.lang.String getCanonicalPath() throws java.io.IOException
Returns the canonical form of this File object’s pathname. The precise definition of canonical form is system-dependent, but it usually specifies an absolute pathname in which all relative references and references to the current user directory have been completely resolved. The canonical form of a pathname of a nonexistent file may not be defined.
getParent
Returns the parent part of the pathname of this File object, or null if the name has no parent part. The parent part is generally everything leading up to the last occurrence of the separator character, although the precise definition is system dependent. On UNIX, for example, the parent part of «/usr/lib» is «/usr» , whose parent part is «/» , which in turn has no parent. On Windows platforms, the parent part of «c:\java» is «c:\» , which in turn has no parent.
getParentFile
Returns the VirtualFile representing the parent directory of this VirtualFile object, or null if this is the root file of the VirtualFileSystem.
Class File
The conversion of a pathname string to or from an abstract pathname is inherently system-dependent. When an abstract pathname is converted into a pathname string, each name is separated from the next by a single copy of the default separator character. The default name-separator character is defined by the system property file.separator , and is made available in the public static fields separator and separatorChar of this class. When a pathname string is converted into an abstract pathname, the names within it may be separated by the default name-separator character or by any other name-separator character that is supported by the underlying system.
A pathname, whether abstract or in string form, may be either absolute or relative. An absolute pathname is complete in that no other information is required in order to locate the file that it denotes. A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir , and is typically the directory in which the Java virtual machine was invoked.
The parent of an abstract pathname may be obtained by invoking the getParent() method of this class and consists of the pathname’s prefix and each name in the pathname’s name sequence except for the last. Each directory’s absolute pathname is an ancestor of any File object with an absolute abstract pathname which begins with the directory’s absolute pathname. For example, the directory denoted by the abstract pathname «/usr» is an ancestor of the directory denoted by the pathname «/usr/local/bin» .
- For UNIX platforms, the prefix of an absolute pathname is always «/» . Relative pathnames have no prefix. The abstract pathname denoting the root directory has the prefix «/» and an empty name sequence.
- For Microsoft Windows platforms, the prefix of a pathname that contains a drive specifier consists of the drive letter followed by «:» and possibly followed by «\\» if the pathname is absolute. The prefix of a UNC pathname is «\\\\» ; the hostname and the share name are the first two names in the name sequence. A relative pathname that does not specify a drive has no prefix.
Instances of this class may or may not denote an actual file-system object such as a file or a directory. If it does denote such an object then that object resides in a partition. A partition is an operating system-specific portion of storage for a file system. A single storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may contain multiple partitions. The object, if any, will reside on the partition named by some ancestor of the absolute form of this pathname.
A file system may implement restrictions to certain operations on the actual file-system object, such as reading, writing, and executing. These restrictions are collectively known as access permissions. The file system may have multiple sets of access permissions on a single object. For example, one set may apply to the object’s owner, and another may apply to all other users. The access permissions on an object may cause some methods in this class to fail.
Instances of the File class are immutable; that is, once created, the abstract pathname represented by a File object will never change.
Interoperability with java.nio.file package
The java.nio.file package defines interfaces and classes for the Java virtual machine to access files, file attributes, and file systems. This API may be used to overcome many of the limitations of the java.io.File class. The toPath method may be used to obtain a Path that uses the abstract path represented by a File object to locate a file. The resulting Path may be used with the Files class to provide more efficient and extensive access to additional file operations, file attributes, and I/O exceptions to help diagnose errors when an operation on a file fails.