8366102: Clarification Needed: Symbolic Link Handling in File API Specifications

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2025-09-04 21:58:08 +00:00
parent 945aaf8932
commit 581070715a

View File

@ -80,17 +80,22 @@ import jdk.internal.util.StaticProperty;
* {@code user.dir}, and is typically the directory in which the Java
* virtual machine was invoked.
*
* <p> Unless otherwise noted, {@linkplain java.nio.file##links symbolic links}
* are automatically redirected to the <i>target</i> of the link, whether they
* are provided by a pathname string or via a {@code File} object.
* <p> Many operating systems and file systems have support for
* {@linkplain java.nio.file##links symbolic links}.
* A symbolic link is a special file that serves as a reference to another file.
* Unless otherwise specified, symbolic links are transparent to applications
* and operations on files that are symbolic links are automatically redirected
* to the target of the link. Methods that only operate on the abstract
* pathname do not access the file system and thus do not resolve symbolic
* links.
*
* <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
* the {@link #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 {@code File}
* object with an absolute abstract pathname which begins with the directory's
* absolute pathname. For example, the directory denoted by the abstract
* pathname {@code "/usr"} is an ancestor of the directory denoted by the
* absolute pathname. For example, the directory located by the abstract
* pathname {@code "/usr"} is an ancestor of the directory located by the
* pathname {@code "/usr/local/bin"}.
*
* <p> The prefix concept is used to handle root directories on UNIX platforms,
@ -113,8 +118,8 @@ import jdk.internal.util.StaticProperty;
*
* </ul>
*
* <p> 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
* <p> Instances of this class may or may not locate an actual file-system
* object such as a file or a directory. If it does locate such an object
* then that object resides in a <i>partition</i>. 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
@ -448,12 +453,12 @@ public class File
/* -- Path-component accessors -- */
/**
* Returns the name of the file or directory denoted by this abstract
* Returns the name component of this abstract
* pathname. This is just the last name in the pathname's name
* sequence. If the pathname's name sequence is empty, then the empty
* string is returned.
*
* @return The name of the file or directory denoted by this abstract
* @return The name component of this abstract
* pathname, or the empty string if this pathname's name sequence
* is empty
*/
@ -592,7 +597,7 @@ public class File
* symbolic links, and converting drive letters to a standard case (on
* Microsoft Windows platforms).
*
* <p> Every pathname that denotes an existing file or directory has a
* <p> Every pathname that locates an existing file or directory has a
* unique canonical form. Every pathname that denotes a nonexistent file
* or directory also has a unique canonical form. The canonical form of
* the pathname of a nonexistent file or directory may be different from
@ -601,7 +606,7 @@ public class File
* file or directory may be different from the canonical form of the same
* pathname after the file or directory is deleted.
*
* @return The canonical pathname string denoting the same file or
* @return The canonical pathname string locating the same file or
* directory as this abstract pathname
*
* @throws IOException
@ -623,7 +628,7 @@ public class File
* Returns the canonical form of this abstract pathname. Equivalent to
* <code>new&nbsp;File(this.{@link #getCanonicalPath})</code>.
*
* @return The canonical pathname string denoting the same file or
* @return The canonical pathname string locating the same file or
* directory as this abstract pathname
*
* @throws IOException
@ -656,7 +661,7 @@ public class File
/**
* Converts this abstract pathname into a {@code file:} URL. The
* exact form of the URL is system-dependent. If it can be determined that
* the file denoted by this abstract pathname is a directory, then the
* the file located by this abstract pathname is a directory, then the
* resulting URL will end with a slash.
*
* @return A URL object representing the equivalent file URL
@ -689,7 +694,7 @@ public class File
* Constructs a {@code file:} URI that represents this abstract pathname.
*
* <p> The exact form of the URI is system-dependent. If it can be
* determined that the file denoted by this abstract pathname is a
* determined that the file located by this abstract pathname is a
* directory, then the resulting URI will end with a slash.
*
* <p> For a given abstract pathname <i>f</i>, it is guaranteed that
@ -740,13 +745,13 @@ public class File
/* -- Attribute accessors -- */
/**
* Tests whether the application can read the file denoted by this
* Tests whether the application can read the file located by this
* abstract pathname. On some platforms it may be possible to start the
* Java virtual machine with special privileges that allow it to read
* files that are marked as unreadable. Consequently, this method may return
* {@code true} even though the file does not have read permissions.
*
* @return {@code true} if and only if the file specified by this
* @return {@code true} if and only if the file located by this
* abstract pathname exists <em>and</em> can be read by the
* application; {@code false} otherwise
*/
@ -758,14 +763,14 @@ public class File
}
/**
* Tests whether the application can modify the file denoted by this
* Tests whether the application can modify the file located by this
* abstract pathname. On some platforms it may be possible to start the
* Java virtual machine with special privileges that allow it to modify
* files that are marked read-only. Consequently, this method may return
* {@code true} even though the file is marked read-only.
*
* @return {@code true} if and only if the file system actually
* contains a file denoted by this abstract pathname <em>and</em>
* contains a file located by this abstract pathname <em>and</em>
* the application is allowed to write to the file;
* {@code false} otherwise.
*/
@ -777,10 +782,10 @@ public class File
}
/**
* Tests whether the file or directory denoted by this abstract pathname
* Tests whether the file or directory located by this abstract pathname
* exists.
*
* @return {@code true} if and only if the file or directory denoted
* @return {@code true} if and only if the file or directory located
* by this abstract pathname exists; {@code false} otherwise
*/
public boolean exists() {
@ -791,7 +796,7 @@ public class File
}
/**
* Tests whether the file denoted by this abstract pathname is a
* Tests whether the file located by this abstract pathname is a
* directory.
*
* <p> Where it is required to distinguish an I/O exception from the case
@ -800,7 +805,7 @@ public class File
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return {@code true} if and only if the file denoted by this
* @return {@code true} if and only if the file located by this
* abstract pathname exists <em>and</em> is a directory;
* {@code false} otherwise
*/
@ -812,7 +817,7 @@ public class File
}
/**
* Tests whether the file denoted by this abstract pathname is a normal
* Tests whether the file located by this abstract pathname is a normal
* file. A file is <em>normal</em> if it is not a directory and, in
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
@ -823,7 +828,7 @@ public class File
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return {@code true} if and only if the file denoted by this
* @return {@code true} if and only if the file located by this
* abstract pathname exists <em>and</em> is a normal file;
* {@code false} otherwise
*/
@ -835,7 +840,7 @@ public class File
}
/**
* Tests whether the file named by this abstract pathname is a hidden
* Tests whether the file located by this abstract pathname is a hidden
* file. The exact definition of <em>hidden</em> is system-dependent. On
* UNIX systems, a file is considered to be hidden if its name begins with
* a period character ({@code '.'}). On Microsoft Windows systems, a file
@ -849,7 +854,7 @@ public class File
* with a period character. On Windows systems, a symbolic link is
* considered hidden if its target is so marked in the filesystem.
*
* @return {@code true} if and only if the file denoted by this
* @return {@code true} if and only if the file located by this
* abstract pathname is hidden according to the conventions of the
* underlying platform
*
@ -863,7 +868,7 @@ public class File
}
/**
* Returns the time that the file denoted by this abstract pathname was
* Returns the time that the file located by this abstract pathname was
* last modified.
*
* @apiNote
@ -897,8 +902,8 @@ public class File
}
/**
* Returns the length of the file denoted by this abstract pathname.
* The return value is unspecified if this pathname denotes a directory.
* Returns the length of the file located by this abstract pathname.
* The return value is unspecified if this pathname locates a directory.
*
* <p> Where it is required to distinguish an I/O exception from the case
* that {@code 0L} is returned, or where several attributes of the same file
@ -906,10 +911,10 @@ public class File
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return The length, in bytes, of the file denoted by this abstract
* @return The length, in bytes, of the file located by this abstract
* pathname, or {@code 0L} if the file does not exist. Some
* operating systems may return {@code 0L} for pathnames
* denoting system-dependent entities such as devices or pipes.
* locating system-dependent entities such as devices or pipes.
*/
public long length() {
if (isInvalid()) {
@ -935,7 +940,7 @@ public class File
*
* @return {@code true} if the named file does not exist and was
* successfully created; {@code false} if the named file
* already exists
* already exists, including if it is a symbolic link
*
* @throws IOException
* If an I/O error occurred
@ -950,9 +955,9 @@ public class File
}
/**
* Deletes the file or directory denoted by this abstract pathname. If
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted. If this pathname denotes a symbolic link, then the
* Deletes the file or directory located by this abstract pathname. If
* this pathname locates a directory, then the directory must be empty in
* order to be deleted. If this pathname locates a symbolic link, then the
* link itself, not its target, will be deleted.
*
* <p> Note that the {@link java.nio.file.Files} class defines the {@link
@ -971,9 +976,9 @@ public class File
}
/**
* Requests that the file or directory denoted by this abstract
* Requests that the file or directory located by this abstract
* pathname be deleted when the virtual machine terminates.
* If this pathname denotes a symbolic link, then the
* If this pathname locates a symbolic link, then the
* link itself, not its target, will be deleted.
* Files (or directories) are deleted in the reverse order that
* they are registered. Invoking this method to delete a file or
@ -1003,12 +1008,12 @@ public class File
/**
* Returns an array of strings naming the files and directories in the
* directory denoted by this abstract pathname.
* directory located by this abstract pathname.
*
* <p> If this abstract pathname does not denote a directory, then this
* <p> If this abstract pathname does not locate a directory, then this
* method returns {@code null}. Otherwise an array of strings is
* returned, one for each file or directory in the directory. Names
* denoting the directory itself and the directory's parent directory are
* locating the directory itself and the directory's parent directory are
* not included in the result. Each string is a file name rather than a
* complete path.
*
@ -1023,9 +1028,9 @@ public class File
* may be more responsive when working with remote directories.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
* directory located by this abstract pathname. The array will be
* empty if the directory is empty. Returns {@code null} if
* this abstract pathname does not denote a directory, or if an
* this abstract pathname does not locate a directory, or if an
* I/O error occurs.
*/
public String[] list() {
@ -1034,13 +1039,13 @@ public class File
/**
* Returns an array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The strings are
* directory located by this abstract pathname. The strings are
* ensured to represent normalized paths.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
* directory located by this abstract pathname. The array will be
* empty if the directory is empty. Returns {@code null} if
* this abstract pathname does not denote a directory, or if an
* this abstract pathname does not locate a directory, or if an
* I/O error occurs.
*/
private final String[] normalizedList() {
@ -1060,7 +1065,7 @@ public class File
/**
* Returns an array of strings naming the files and directories in the
* directory denoted by this abstract pathname that satisfy the specified
* directory located by this abstract pathname that satisfy the specified
* filter. The behavior of this method is the same as that of the
* {@link #list()} method, except that the strings in the returned array
* must satisfy the filter. If the given {@code filter} is {@code null}
@ -1068,16 +1073,16 @@ public class File
* and only if the value {@code true} results when the {@link
* FilenameFilter#accept FilenameFilter.accept(File,&nbsp;String)} method
* of the filter is invoked on this abstract pathname and the name of a
* file or directory in the directory that it denotes.
* file or directory in the directory that it locates.
*
* @param filter
* A filename filter
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname that were accepted
* directory located by this abstract pathname that were accepted
* by the given {@code filter}. The array will be empty if the
* directory is empty or if no names were accepted by the filter.
* Returns {@code null} if this abstract pathname does not denote
* Returns {@code null} if this abstract pathname does not locate
* a directory, or if an I/O error occurs.
*
* @see java.nio.file.Files#newDirectoryStream(Path,String)
@ -1097,13 +1102,13 @@ public class File
}
/**
* Returns an array of abstract pathnames denoting the files in the
* directory denoted by this abstract pathname.
* Returns an array of abstract pathnames locating the files in the
* directory located by this abstract pathname.
*
* <p> If this abstract pathname does not denote a directory, then this
* <p> If this abstract pathname does not locate a directory, then this
* method returns {@code null}. Otherwise an array of {@code File} objects
* is returned, one for each file or directory in the directory. Pathnames
* denoting the directory itself and the directory's parent directory are
* locating the directory itself and the directory's parent directory are
* not included in the result. Each resulting abstract pathname is
* constructed from this abstract pathname using the {@link #File(File,
* String) File(File,&nbsp;String)} constructor. Therefore if this
@ -1121,10 +1126,10 @@ public class File
* directory. This may use less resources when working with very large
* directories.
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
* @return An array of abstract pathnames locating the files and
* directories in the directory located by this abstract pathname.
* The array will be empty if the directory is empty. Returns
* {@code null} if this abstract pathname does not denote a
* {@code null} if this abstract pathname does not locate a
* directory, or if an I/O error occurs.
*
* @since 1.2
@ -1141,8 +1146,8 @@ public class File
}
/**
* Returns an array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname that
* Returns an array of abstract pathnames locating the files and
* directories in the directory located by this abstract pathname that
* satisfy the specified filter. The behavior of this method is the same
* as that of the {@link #listFiles()} method, except that the pathnames in
* the returned array must satisfy the filter. If the given {@code filter}
@ -1151,15 +1156,15 @@ public class File
* the {@link FilenameFilter#accept
* FilenameFilter.accept(File,&nbsp;String)} method of the filter is
* invoked on this abstract pathname and the name of a file or directory in
* the directory that it denotes.
* the directory that it locates.
*
* @param filter
* A filename filter
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
* @return An array of abstract pathnames locating the files and
* directories in the directory located by this abstract pathname.
* The array will be empty if the directory is empty. Returns
* {@code null} if this abstract pathname does not denote a
* {@code null} if this abstract pathname does not locate a
* directory, or if an I/O error occurs.
*
* @since 1.2
@ -1177,8 +1182,8 @@ public class File
}
/**
* Returns an array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname that
* Returns an array of abstract pathnames locating the files and
* directories in the directory located by this abstract pathname that
* satisfy the specified filter. The behavior of this method is the same
* as that of the {@link #listFiles()} method, except that the pathnames in
* the returned array must satisfy the filter. If the given {@code filter}
@ -1190,10 +1195,10 @@ public class File
* @param filter
* A file filter
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
* @return An array of abstract pathnames locating the files and
* directories in the directory located by this abstract pathname.
* The array will be empty if the directory is empty. Returns
* {@code null} if this abstract pathname does not denote a
* {@code null} if this abstract pathname does not locate a
* directory, or if an I/O error occurs.
*
* @since 1.2
@ -1255,8 +1260,8 @@ public class File
}
/**
* Renames the file denoted by this abstract pathname. If this pathname
* denotes a symbolic link, then the link itself, not its target, will be
* Renames the file located by this abstract pathname. If this pathname
* locates a symbolic link, then the link itself, not its target, will be
* renamed.
*
* <p> Many aspects of the behavior of this method are inherently
@ -1291,7 +1296,7 @@ public class File
}
/**
* Sets the last-modified time of the file or directory named by this
* Sets the last-modified time of the file or directory located by this
* abstract pathname.
*
* <p> All platforms support file-modification times to the nearest second,
@ -1320,7 +1325,7 @@ public class File
}
/**
* Marks the file or directory named by this abstract pathname so that
* Marks the file or directory located by this abstract pathname so that
* only read operations are allowed. After invoking this method the file
* or directory will not change until it is either deleted or marked
* to allow write access. On some platforms it may be possible to start the
@ -1341,7 +1346,8 @@ public class File
}
/**
* Sets the owner's or everybody's write permission for this abstract
* Sets the owner's or everybody's write permission of the file or
* directory located by this abstract
* pathname. On some platforms it may be possible to start the Java virtual
* machine with special privileges that allow it to modify files that
* disallow write operations.
@ -1375,7 +1381,8 @@ public class File
}
/**
* A convenience method to set the owner's write permission for this abstract
* A convenience method to set the owner's write permission for the file
* or directory located by this abstract
* pathname. On some platforms it may be possible to start the Java virtual
* machine with special privileges that allow it to modify files that
* disallow write operations.
@ -1402,7 +1409,8 @@ public class File
}
/**
* Sets the owner's or everybody's read permission for this abstract
* Sets the owner's or everybody's read permission for the file or directory
* located by this abstract
* pathname. On some platforms it may be possible to start the Java virtual
* machine with special privileges that allow it to read files that are
* marked as unreadable.
@ -1442,7 +1450,8 @@ public class File
}
/**
* A convenience method to set the owner's read permission for this abstract
* A convenience method to set the owner's read permission for the file
* or directory located by this abstract
* pathname. On some platforms it may be possible to start the Java virtual
* machine with special privileges that allow it to read files that are
* marked as unreadable.
@ -1475,7 +1484,8 @@ public class File
}
/**
* Sets the owner's or everybody's execute permission for this abstract
* Sets the owner's or everybody's execute permission for the file or
* directory located by this abstract
* pathname. On some platforms it may be possible to start the Java virtual
* machine with special privileges that allow it to execute files that are
* not marked executable.
@ -1515,7 +1525,8 @@ public class File
}
/**
* A convenience method to set the owner's execute permission for this
* A convenience method to set the owner's execute permission for the file
* or directory located by this
* abstract pathname. On some platforms it may be possible to start the Java
* virtual machine with special privileges that allow it to execute files
* that are not marked executable.
@ -1548,7 +1559,7 @@ public class File
}
/**
* Tests whether the application can execute the file denoted by this
* Tests whether the application can execute the file located by this
* abstract pathname. On some platforms it may be possible to start the
* Java virtual machine with special privileges that allow it to execute
* files that are not marked executable. Consequently, this method may return
@ -1794,7 +1805,7 @@ public class File
* returns successfully then it is guaranteed that:
*
* <ol>
* <li> The file denoted by the returned abstract pathname did not exist
* <li> The file located by the returned abstract pathname did not exist
* before this method was invoked, and
* <li> Neither this method nor any of its variants will return the same
* abstract pathname again in the current invocation of the virtual
@ -1837,7 +1848,7 @@ public class File
* to have any effect upon the temporary directory used by this method.
*
* <p> If the {@code directory} argument is not {@code null} and its
* abstract pathname is valid and denotes an existing, writable directory,
* abstract pathname is valid and locates an existing, writable directory,
* then the file will be created in that directory. Otherwise the file will
* not be created and an {@code IOException} will be thrown. Under no
* circumstances will a directory be created at the location specified by
@ -1854,7 +1865,7 @@ public class File
* {@code null} if the default temporary-file
* directory is to be used
*
* @return An abstract pathname denoting a newly-created empty file
* @return An abstract pathname locating a newly-created empty file
*
* @throws IllegalArgumentException
* If the {@code prefix} argument contains fewer than three
@ -1911,7 +1922,7 @@ public class File
* name; may be {@code null}, in which case the
* suffix {@code ".tmp"} will be used
*
* @return An abstract pathname denoting a newly-created empty file
* @return An abstract pathname locating a newly-created empty file
*
* @throws IllegalArgumentException
* If the {@code prefix} argument contains fewer than three
@ -1934,7 +1945,9 @@ public class File
* Compares two abstract pathnames lexicographically. The ordering
* defined by this method depends upon the underlying system. On UNIX
* systems, alphabetic case is significant in comparing pathnames; on
* Microsoft Windows systems it is not.
* Microsoft Windows systems it is not. This method only compares the
* abstract pathnames; it does not access the file system and the file is
* not required to exist.
*
* @param pathname The abstract pathname to be compared to this abstract
* pathname
@ -1958,11 +1971,9 @@ public class File
* abstract pathname. Whether or not two abstract
* pathnames are equal depends upon the underlying operating system.
* On UNIX systems, alphabetic case is significant in comparing pathnames;
* on Microsoft Windows systems it is not.
*
* @apiNote This method only tests whether the abstract pathnames are equal;
* it does not access the file system and the file is not required
* to exist.
* on Microsoft Windows systems it is not. This method only tests whether
* the abstract pathnames are equal; it does not access the file system and
* the file is not required to exist.
*
* @param obj The object to be compared with this abstract pathname
*