Class VirtualFile
- java.lang.Object
-
- jenkins.util.VirtualFile
-
- All Implemented Interfaces:
Serializable
,Comparable<VirtualFile>
public abstract class VirtualFile extends Object implements Comparable<VirtualFile>, Serializable
Abstraction overFile
,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, useforFile(File)
orFilePath.toVirtualFile()
How are VirtualFile and FilePath different?
FilePath abstracts away
File
s on machines that are connected overChannel
, whereasVirtualFile
makes no assumption about where the actual files are, or whether there really existsFile
s somewhere. This makes VirtualFile more abstract.Opening files from other machines
WhileVirtualFile
is markedSerializable
, it is not safe in general to transfer over a Remoting channel. (For example, an implementation fromforFilePath(hudson.FilePath)
could be sent on the same channel, but an implementation fromforFile(java.io.File)
will not.) Thus callers should assume that methods such asopen()
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 fromopen()
usingRemoteInputStream
would wind up transferring the file from the service to the Jenkins master and then on to an agent. Similarly, ifDirectoryBrowserSupport
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 supportstoExternalURL()
.- Since:
- 1.532
- See Also:
DirectoryBrowserSupport
,FilePath
, Serialized Form
-
-
Constructor Summary
Constructors Constructor Description VirtualFile()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description abstract boolean
canRead()
Checks whether this file can be read.abstract VirtualFile
child(String name)
Obtains a child file.int
compareTo(VirtualFile o)
Does case-insensitive comparison.boolean
containsSymLinkChild(OpenOption... openOptions)
boolean
containsTmpDirChild(OpenOption... openOptions)
boolean
equals(Object obj)
Compares according totoURI()
.abstract boolean
exists()
Checks whether this file exists.static VirtualFile
forFile(File f)
Creates a virtual file wrapper for a local file.static VirtualFile
forFilePath(FilePath f)
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
getParent()
Gets the parent file.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
isDirectory()
Checks whether this file exists and is a directory.abstract boolean
isFile()
Checks whether this file exists and is a plain file.abstract long
lastModified()
Gets the file timestamp.abstract long
length()
Gets the file length.abstract VirtualFile[]
list()
Lists children of this directory.String[]
list(String glob)
Deprecated.uselist(String, String, boolean)
insteadCollection<String>
list(String includes, String excludes, boolean useDefaultExcludes)
Lists recursive files of this directory with pattern matching.Collection<String>
list(String includes, String excludes, boolean useDefaultExcludes, OpenOption... openOptions)
Lists recursive files of this directory with pattern matching.VirtualFile[]
list(OpenOption... openOptions)
Lists children of this directory.List<VirtualFile>
listOnlyDescendants()
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.InputStream
open(OpenOption... openOptions)
Opens an input stream on the file so its contents can be read.String
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
supportIsDescendant()
Determine if the implementation supports theisDescendant(String)
method TODO un-restrict it in a weekly after the patchboolean
supportsQuickRecursiveListing()
URL
toExternalURL()
Optionally obtains a URL which may be used to retrieve file contents from any process on any node.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.
-
-
-
Method Detail
-
getName
@NonNull public abstract String 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
@NonNull public abstract URI 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
public abstract VirtualFile getParent()
Gets the parent file. Need only operate within the originally given root.- Returns:
- the parent
-
isDirectory
public abstract boolean isDirectory() throws IOException
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
public abstract boolean isFile() throws IOException
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
@CheckForNull public String readLink() throws IOException
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
public abstract boolean exists() throws IOException
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
@NonNull public abstract VirtualFile[] list() throws IOException
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 IOException
Lists 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 @NonNull public String[] list(String glob) throws IOException
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
@NonNull public abstract VirtualFile child(@NonNull String name)
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
public abstract long length() throws IOException
Gets the file length.- Returns:
- a length, or 0 if inapplicable (e.g. a directory)
- Throws:
IOException
- if checking the length failed
-
lastModified
public abstract long lastModified() throws IOException
Gets the file timestamp.- Returns:
- a length, or 0 if inapplicable
- Throws:
IOException
- if checking the timestamp failed
-
mode
public int mode() throws IOException
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
public abstract boolean canRead() throws IOException
Checks whether this file can be read.- Returns:
- true normally
- Throws:
IOException
- if checking status failed
-
open
public abstract InputStream open() throws IOException
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
public final int compareTo(VirtualFile o)
Does case-insensitive comparison.- Specified by:
compareTo
in interfaceComparable<VirtualFile>
-
hashCode
public final int hashCode()
Hashes according totoURI()
.
-
run
public <V> V run(hudson.remoting.Callable<V,IOException> callable) throws IOException
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
@CheckForNull public URL toExternalURL() throws IOException
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:
toURI()
-
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
public static VirtualFile forFile(File f)
Creates a virtual file wrapper for a local file.- Parameters:
f
- a disk file (need not exist)- Returns:
- a wrapper
-
forFilePath
public static VirtualFile forFilePath(FilePath f)
Creates a virtual file wrapper for a remotable file.- Parameters:
f
- a local or remote file (need not exist)- Returns:
- a wrapper
-
-