Class VirtualFile
- All Implemented Interfaces:
Serializable
,Comparable<VirtualFile>
File
, FilePath
, or other items such as network resources or ZIP entries.
Assumed to be read-only and makes very limited assumptions, just enough to display content and traverse directories.
To obtain a VirtualFile
representation for an existing file, use forFile(File)
or FilePath.toVirtualFile()
How are VirtualFile and FilePath different?
FilePath abstracts away File
s on machines that are connected over Channel
, whereas
VirtualFile
makes no assumption about where the actual files are, or whether there really exists
File
s somewhere. This makes VirtualFile more abstract.
Opening files from other machines
WhileVirtualFile
is marked Serializable
,
it is not safe in general to transfer over a Remoting channel.
(For example, an implementation from forFilePath(hudson.FilePath)
could be sent on the same channel,
but an implementation from forFile(java.io.File)
will not.)
Thus callers should assume that methods such as open()
will work
only on the node on which the object was created.
Since some implementations may in fact use external file storage,
callers may request optional APIs to access those services more efficiently.
Otherwise, for example, a plugin copying a file
previously saved by ArtifactManager
to an external storage service
which tunneled a stream from open()
using RemoteInputStream
would wind up transferring the file from the service to the Jenkins master and then on to an agent.
Similarly, if DirectoryBrowserSupport
rendered a link to an in-Jenkins URL,
a large file could be transferred from the service to the Jenkins master and then on to the browser.
To avoid this overhead, callers may check whether an implementation supports toExternalURL()
.
- Since:
- 1.532
- See Also:
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionabstract boolean
canRead()
Checks whether this file can be read.abstract VirtualFile
Obtains a child file.final int
Does case-insensitive comparison.boolean
containsSymLinkChild
(OpenOption... openOptions) boolean
containsTmpDirChild
(OpenOption... openOptions) final boolean
Compares according totoURI()
.abstract boolean
exists()
Checks whether this file exists.static VirtualFile
Creates a virtual file wrapper for a local file.static VirtualFile
Creates a virtual file wrapper for a remotable file.abstract String
getName()
Gets the base name, meaning just the last portion of the path name without any directories.abstract VirtualFile
Gets the parent file.final int
hashCode()
Hashes according totoURI()
.boolean
hasSymlink
(OpenOption... openOptions) Determines when a VirtualFile has a recognized symlink.boolean
isDescendant
(String childRelativePath) Check if the relative path is really a descendant of this folder, following the symbolic links.abstract boolean
Checks whether this file exists and is a directory.abstract boolean
isFile()
Checks whether this file exists and is a plain file.abstract long
Gets the file timestamp.abstract long
length()
Gets the file length.abstract VirtualFile[]
list()
Lists children of this directory.String[]
Deprecated.Lists recursive files of this directory with pattern matching.list
(String includes, String excludes, boolean useDefaultExcludes, OpenOption... openOptions) Lists recursive files of this directory with pattern matching.list
(OpenOption... openOptions) Lists children of this directory.Lists only the children that are descendant of the root directory (not necessarily the current VirtualFile).int
mode()
Gets the file’s Unix mode, if meaningful.abstract InputStream
open()
Opens an input stream on the file so its contents can be read.open
(OpenOption... openOptions) Opens an input stream on the file so its contents can be read.readLink()
If this file is a symlink, returns the link target.<V> V
run
(hudson.remoting.Callable<V, IOException> callable) Does some calculations in batch.boolean
Determine if the implementation supports theisDescendant(String)
method TODO un-restrict it in a weekly after the patchboolean
Optionally obtains a URL which may be used to retrieve file contents from any process on any node.final String
toString()
DisplaystoURI()
.abstract URI
toURI()
Gets a URI.int
zip
(OutputStream outputStream, String includes, String excludes, boolean useDefaultExcludes, String prefix, OpenOption... openOptions) Create a ZIP archive from the list of folders/files using the includes and excludes to filter them.
-
Constructor Details
-
VirtualFile
public VirtualFile()
-
-
Method Details
-
getName
Gets the base name, meaning just the last portion of the path name without any directories. For a “root directory” this may be the empty string.- Returns:
- a simple name (no slashes)
-
toURI
Gets a URI. Should at least uniquely identify this virtual file within its root, but not necessarily globally.When
toExternalURL()
is implemented, that same value could be used here, unless some sort of authentication is also embedded.- Returns:
- a URI (need not be absolute)
-
getParent
Gets the parent file. Need only operate within the originally given root.- Returns:
- the parent
-
isDirectory
Checks whether this file exists and is a directory.- Returns:
- true if it is a directory, false if a file or nonexistent
- Throws:
IOException
- in case checking status failed
-
isFile
Checks whether this file exists and is a plain file.- Returns:
- true if it is a file, false if a directory or nonexistent
- Throws:
IOException
- in case checking status failed
-
readLink
If this file is a symlink, returns the link target.The default implementation always returns null. Some implementations may not support symlinks under any conditions.
- Returns:
- a target (typically a relative path in some format), or null if this is not a link
- Throws:
IOException
- if reading the link, or even determining whether this file is a link, failed- Since:
- 2.118
-
exists
Checks whether this file exists. The behavior is undefined for symlinks; if in doubt, checkreadLink()
first.- Returns:
- true if it is a plain file or directory, false if nonexistent
- Throws:
IOException
- in case checking status failed
-
list
Lists children of this directory. Only one level deep.- Returns:
- a list of children (files and subdirectories); empty for a file or nonexistent directory
- Throws:
IOException
- if this directory exists but listing was not possible for some other reason
-
list
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) @NonNull public VirtualFile[] list(OpenOption... openOptions) throws IOException Lists children of this directory. Only one level deep. This is intended to allow the caller to provideLinkOption.NOFOLLOW_LINKS
to ignore symlinks. However, this cannot be enforced. The base implementation here in VirtualFile ignores the openOptions. Some VirtualFile subclasses may not be able to provide an implementation in which NOFOLLOW_LINKS is used or makes sense. Implementations are free to ignore openOptions. Some subclasses of VirtualFile may not have a concept of symlinks.- Parameters:
openOptions
- the options to apply when opening.- Returns:
- a list of children (files and subdirectories); empty for a file or nonexistent directory
- Throws:
IOException
- if it could not be opened
-
supportsQuickRecursiveListing
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean supportsQuickRecursiveListing() -
hasSymlink
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean hasSymlink(OpenOption... openOptions) throws IOException Determines when a VirtualFile has a recognized symlink. A recognized symlink can be the file itself or any containing directory between it and the optional root directory. If there is no provided root directory then only the file itself is considered. This base implementation ignores the existence of symlinks.- Parameters:
openOptions
- the various open options to apply to the operation.- Returns:
- True if the file is a symlink or is referenced within a containing symlink. directory before reaching the root directory.
- Throws:
IOException
- If there is a problem accessing the file.
-
listOnlyDescendants
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) @NonNull public List<VirtualFile> listOnlyDescendants() throws IOExceptionLists only the children that are descendant of the root directory (not necessarily the current VirtualFile). Only one level deep.- Returns:
- a list of descendant children (files and subdirectories); empty for a file or nonexistent directory
- Throws:
IOException
- if this directory exists but listing was not possible for some other reason
-
list
Deprecated.uselist(String, String, boolean)
instead- Throws:
IOException
-
list
@NonNull public Collection<String> list(@NonNull String includes, @CheckForNull String excludes, boolean useDefaultExcludes) throws IOException Lists recursive files of this directory with pattern matching.The default implementation calls
list()
recursively insiderun(hudson.remoting.Callable<V, java.io.IOException>)
and applies filtering to the result. Implementations may wish to override this more efficiently.- Parameters:
includes
- comma-separated Ant-style globs as perUtil.createFileSet(File, String, String)
using/
as a path separator; the empty string means no matches (useSelectorUtils.DEEP_TREE_MATCH
if you want to match everything except some excludes)excludes
- optional excludes in similar format toincludes
useDefaultExcludes
- as perAbstractFileSet.setDefaultexcludes(boolean)
- Returns:
- a list of
/
-separated relative names of children (files directly inside or in subdirectories) - Throws:
IOException
- if this is not a directory, or listing was not possible for some other reason- Since:
- 2.118
-
list
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) @NonNull public Collection<String> list(@NonNull String includes, @CheckForNull String excludes, boolean useDefaultExcludes, OpenOption... openOptions) throws IOException Lists recursive files of this directory with pattern matching.The default implementation calls
list()
recursively insiderun(hudson.remoting.Callable<V, java.io.IOException>)
and applies filtering to the result. Implementations may wish to override this more efficiently. This method allows the user to specify that symlinks should not be followed by passing LinkOption.NOFOLLOW_LINKS as true. However, some implementations may not be able to reliably prevent link following. The base implementation here in VirtualFile ignores this parameter.- Parameters:
includes
- comma-separated Ant-style globs as perUtil.createFileSet(File, String, String)
using/
as a path separator; the empty string means no matches (useSelectorUtils.DEEP_TREE_MATCH
if you want to match everything except some excludes)excludes
- optional excludes in similar format toincludes
useDefaultExcludes
- as perAbstractFileSet.setDefaultexcludes(boolean)
openOptions
- the options to apply when opening.- Returns:
- a list of
/
-separated relative names of children (files directly inside or in subdirectories) - Throws:
IOException
- if this is not a directory, or listing was not possible for some other reason- Since:
- 2.275 and 2.263.2
-
containsSymLinkChild
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean containsSymLinkChild(OpenOption... openOptions) throws IOException - Throws:
IOException
-
containsTmpDirChild
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean containsTmpDirChild(OpenOption... openOptions) throws IOException - Throws:
IOException
-
zip
public int zip(OutputStream outputStream, String includes, String excludes, boolean useDefaultExcludes, String prefix, OpenOption... openOptions) throws IOException Create a ZIP archive from the list of folders/files using the includes and excludes to filter them.The default implementation calls other existing methods to list the folders/files, then retrieve them and zip them all.
- Parameters:
includes
- comma-separated Ant-style globs as perUtil.createFileSet(File, String, String)
using/
as a path separator; the empty string means no matches (useSelectorUtils.DEEP_TREE_MATCH
if you want to match everything except some excludes)excludes
- optional excludes in similar format toincludes
useDefaultExcludes
- as perAbstractFileSet.setDefaultexcludes(boolean)
prefix
- the partial path that will be added before each entry inside the archive. If non-empty, a trailing slash will be enforced.openOptions
- the options to apply when opening.- Returns:
- the number of files inside the archive (not the folders)
- Throws:
IOException
- if this is not a directory, or listing was not possible for some other reason- Since:
- 2.275 and 2.263.2
-
child
Obtains a child file.- Parameters:
name
- a relative path, possibly including/
(but not..
)- Returns:
- a representation of that child, whether it actually exists or not
-
length
Gets the file length.- Returns:
- a length, or 0 if inapplicable (e.g. a directory)
- Throws:
IOException
- if checking the length failed
-
lastModified
Gets the file timestamp.- Returns:
- a length, or 0 if inapplicable
- Throws:
IOException
- if checking the timestamp failed
-
mode
Gets the file’s Unix mode, if meaningful. If the file is symlink (seereadLink()
), the mode is that of the link target, not the link itself.- Returns:
- for example, 0644 ~
rw-r--r--
; -1 by default, meaning unknown or inapplicable - Throws:
IOException
- if checking the mode failed- Since:
- 2.118
-
canRead
Checks whether this file can be read.- Returns:
- true normally
- Throws:
IOException
- if checking status failed
-
open
Opens an input stream on the file so its contents can be read.- Returns:
- an open stream
- Throws:
IOException
- if it could not be opened
-
open
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public InputStream open(OpenOption... openOptions) throws IOException Opens an input stream on the file so its contents can be read.- Parameters:
openOptions
- the options to apply when opening.- Returns:
- an open stream
- Throws:
IOException
- if it could not be opened
-
compareTo
Does case-insensitive comparison.- Specified by:
compareTo
in interfaceComparable<VirtualFile>
-
equals
Compares according totoURI()
. -
hashCode
public final int hashCode()Hashes according totoURI()
. -
toString
DisplaystoURI()
. -
run
Does some calculations in batch. For a remote file, this can be much faster than doing the corresponding operations one by one as separate requests. The default implementation just calls the block directly.- Type Parameters:
V
- a value type- Parameters:
callable
- something to run all at once (only helpful if any mentioned files are on the same system)- Returns:
- the callable result
- Throws:
IOException
- if remote communication failed- Since:
- 1.554
-
toExternalURL
Optionally obtains a URL which may be used to retrieve file contents from any process on any node. For example, given cloud storage this might produce a permalink to the file.Only
http
andhttps
protocols are permitted. It is recommended to useRobustHTTPClient.downloadFile
to work with these URLs.This is only meaningful for
isFile()
: no ZIP etc. archiving protocol is defined to allow bulk access to directory trees.Any necessary authentication must be encoded somehow into the URL itself; do not include any tokens or other authentication which might allow access to unrelated files (for example
ArtifactManager
builds from a different job). Authentication should be limited to download, not upload or any other modifications.The URL might be valid for only a limited amount of time or even only a single use; this method should be called anew every time an external URL is required.
- Returns:
- an externally usable URL like
https://gist.githubusercontent.com/ACCT/GISTID/raw/COMMITHASH/FILE
, or null if there is no such support - Throws:
IOException
- Since:
- 2.118
- See Also:
-
supportIsDescendant
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean supportIsDescendant()Determine if the implementation supports theisDescendant(String)
method TODO un-restrict it in a weekly after the patch -
isDescendant
@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean isDescendant(String childRelativePath) throws IOException Check if the relative path is really a descendant of this folder, following the symbolic links. Meant to be used in coordination withchild(String)
. TODO un-restrict it in a weekly after the patch- Throws:
IOException
-
forFile
Creates a virtual file wrapper for a local file.- Parameters:
f
- a disk file (need not exist)- Returns:
- a wrapper
-
forFilePath
Creates a virtual file wrapper for a remotable file.- Parameters:
f
- a local or remote file (need not exist)- Returns:
- a wrapper
-
list(String, String, boolean)
instead