diff --git a/make/java/java/FILES_java.gmk b/make/java/java/FILES_java.gmk index 47179069c1752ca697f722f072598a1e8a104c8b..fdd4b5519125df5ae1570dc7c269f8286697f416 100644 --- a/make/java/java/FILES_java.gmk +++ b/make/java/java/FILES_java.gmk @@ -443,7 +443,6 @@ JAVA_JAVA_java = \ java/io/FileReader.java \ java/io/PipedReader.java \ java/io/StringReader.java \ - java/io/TempFileHelper.java \ java/io/Writer.java \ java/io/BufferedWriter.java \ java/io/PrintWriter.java \ diff --git a/make/java/nio/FILES_java.gmk b/make/java/nio/FILES_java.gmk index cb416fe093263dc271018cf68d819b21adb91de4..9fbeafb48a3a4a2de217195b48b712ea1c07c298 100644 --- a/make/java/nio/FILES_java.gmk +++ b/make/java/nio/FILES_java.gmk @@ -81,12 +81,12 @@ FILES_src = \ java/nio/file/ClosedDirectoryStreamException.java \ java/nio/file/ClosedFileSystemException.java \ java/nio/file/ClosedWatchServiceException.java \ + java/nio/file/CopyMoveHelper.java \ java/nio/file/CopyOption.java \ java/nio/file/DirectoryIteratorException.java \ java/nio/file/DirectoryNotEmptyException.java \ java/nio/file/DirectoryStream.java \ java/nio/file/FileAlreadyExistsException.java \ - java/nio/file/FileRef.java \ java/nio/file/FileStore.java \ java/nio/file/FileSystem.java \ java/nio/file/FileSystemAlreadyExistsException.java \ @@ -116,6 +116,7 @@ FILES_src = \ java/nio/file/StandardCopyOption.java \ java/nio/file/StandardOpenOption.java \ java/nio/file/StandardWatchEventKind.java \ + java/nio/file/TempFileHelper.java \ java/nio/file/WatchEvent.java \ java/nio/file/WatchKey.java \ java/nio/file/WatchService.java \ @@ -127,7 +128,6 @@ FILES_src = \ java/nio/file/attribute/AclEntryType.java \ java/nio/file/attribute/AclFileAttributeView.java \ java/nio/file/attribute/AttributeView.java \ - java/nio/file/attribute/Attributes.java \ java/nio/file/attribute/BasicFileAttributeView.java \ java/nio/file/attribute/BasicFileAttributes.java \ java/nio/file/attribute/DosFileAttributeView.java \ @@ -136,8 +136,6 @@ FILES_src = \ java/nio/file/attribute/FileAttributeView.java \ java/nio/file/attribute/FileOwnerAttributeView.java \ java/nio/file/attribute/FileStoreAttributeView.java \ - java/nio/file/attribute/FileStoreSpaceAttributeView.java \ - java/nio/file/attribute/FileStoreSpaceAttributes.java \ java/nio/file/attribute/FileTime.java \ java/nio/file/attribute/GroupPrincipal.java \ java/nio/file/attribute/UserDefinedFileAttributeView.java \ @@ -246,6 +244,7 @@ FILES_src = \ sun/nio/fs/AbstractAclFileAttributeView.java \ sun/nio/fs/AbstractBasicFileAttributeView.java \ sun/nio/fs/AbstractFileTypeDetector.java \ + sun/nio/fs/AbstractFileSystemProvider.java \ sun/nio/fs/AbstractPath.java \ sun/nio/fs/AbstractPoller.java \ sun/nio/fs/AbstractUserDefinedFileAttributeView.java \ diff --git a/make/mkdemo/Makefile b/make/mkdemo/Makefile index 1e1739467cc8e0f383fcee487c72e35770a6df0a..bb29498d5a746ec785b1568b7db092387c1ec10f 100644 --- a/make/mkdemo/Makefile +++ b/make/mkdemo/Makefile @@ -31,7 +31,7 @@ BUILDDIR = .. PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni nio +SUBDIRS = jni SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting diff --git a/src/share/classes/java/io/BufferedReader.java b/src/share/classes/java/io/BufferedReader.java index b12eaa0d0b550eb958c18142dde2e5b65f998620..e8583e046f07c1d490797c6b385026e900be9129 100644 --- a/src/share/classes/java/io/BufferedReader.java +++ b/src/share/classes/java/io/BufferedReader.java @@ -54,6 +54,7 @@ package java.io; * * @see FileReader * @see InputStreamReader + * @see java.nio.file.Files#newBufferedReader * * @author Mark Reinhold * @since JDK1.1 @@ -374,6 +375,8 @@ public class BufferedReader extends Reader { * stream has been reached * * @exception IOException If an I/O error occurs + * + * @see java.nio.file.Files#readAllLines */ public String readLine() throws IOException { return readLine(false); diff --git a/src/share/classes/java/io/BufferedWriter.java b/src/share/classes/java/io/BufferedWriter.java index 457c73f512d9eab835656046f82a00fd354f8098..4322683d367d270f975efddc897d952a75595e42 100644 --- a/src/share/classes/java/io/BufferedWriter.java +++ b/src/share/classes/java/io/BufferedWriter.java @@ -57,6 +57,7 @@ package java.io; * @see PrintWriter * @see FileWriter * @see OutputStreamWriter + * @see java.nio.file.Files#newBufferedWriter * * @author Mark Reinhold * @since JDK1.1 diff --git a/src/share/classes/java/io/File.java b/src/share/classes/java/io/File.java index 1ff3e936bae6bdc4662e415c76f9af18bc6f8bba..cde70d0b977019b77b32350b2129509b73dbe1de 100644 --- a/src/share/classes/java/io/File.java +++ b/src/share/classes/java/io/File.java @@ -35,8 +35,7 @@ import java.util.ArrayList; import java.security.AccessController; import java.security.SecureRandom; import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.FileAttribute; +import java.nio.file.FileSystems; import sun.security.action.GetPropertyAction; /** @@ -139,9 +138,10 @@ import sun.security.action.GetPropertyAction; * many of the limitations of the {@code java.io.File} class. * The {@link #toPath toPath} method may be used to obtain a {@link * Path} that uses the abstract path represented by a {@code File} object to - * locate a file. The resulting {@code Path} provides more efficient and - * extensive access to file attributes, additional file operations, and I/O - * exceptions to help diagnose errors when an operation on a file fails. + * locate a file. The resulting {@code Path} may be used with the {@link + * java.nio.file.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. * * @author unascribed * @since JDK1.0 @@ -778,6 +778,12 @@ public class File * Tests whether the file denoted by this abstract pathname is a * directory. * + *
Where it is required to distinguish an I/O exception from the case
+ * that the file is not a directory, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return true
if and only if the file denoted by this
* abstract pathname exists and is a directory;
* false
otherwise
@@ -786,8 +792,6 @@ public class File
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
@@ -804,6 +808,12 @@ public class File
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
*
+ *
Where it is required to distinguish an I/O exception from the case
+ * that the file is not a normal file, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return true
if and only if the file denoted by this
* abstract pathname exists and is a normal file;
* false
otherwise
@@ -812,8 +822,6 @@ public class File
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
@@ -853,6 +861,13 @@ public class File
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
+ *
Where it is required to distinguish an I/O exception from the case
+ * where {@code 0L} is returned, or where several attributes of the
+ * same file are required at the same time, or where the time of last
+ * access or the creation time are required, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return A long
value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or 0L
if the
@@ -862,8 +877,6 @@ public class File
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
@@ -877,6 +890,12 @@ 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.
*
+ *
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
+ * are required at the same time, then the {@link
+ * 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
* pathname, or 0L
if the file does not exist. Some
* operating systems may return 0L
for pathnames
@@ -886,8 +905,6 @@ public class File
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long length() {
SecurityManager security = System.getSecurityManager();
@@ -937,11 +954,10 @@ public class File
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted.
*
- *
Note that the {@link Path} class defines the {@link Path#delete - * delete} method to throw an {@link IOException} when a file cannot be - * deleted. This is useful for error reporting and to diagnose why a file - * cannot be deleted. The {@link #toPath toPath} method may be used to - * obtain a {@code Path} representing this abstract pathname. + *
Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
+ * when a file cannot be deleted. This is useful for error reporting and to
+ * diagnose why a file cannot be deleted.
*
* @return true
if and only if the file or directory is
* successfully deleted; false
otherwise
@@ -1009,12 +1025,11 @@ public class File
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
- *
Note that the {@link Path} class defines the {@link - * Path#newDirectoryStream newDirectoryStream} method to open a directory - * and iterate over the names of the files in the directory. This may use - * less resources when working with very large directories. The {@link - * #toPath toPath} method may be used to obtain a {@code Path} representing - * this abstract pathname. + *
Note that the {@link java.nio.file.Files} class defines the {@link + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to + * open a directory and iterate over the names of the files in the directory. + * This may use less resources when working with very large directories, and + * 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 @@ -1061,6 +1076,8 @@ public class File * If a security manager exists and its {@link * SecurityManager#checkRead(String)} method denies read access to * the directory + * + * @see java.nio.file.Files#newDirectoryStream(Path,String) */ public String[] list(FilenameFilter filter) { String names[] = list(); @@ -1095,12 +1112,11 @@ public class File * will appear in any specific order; they are not, in particular, * guaranteed to appear in alphabetical order. * - *
Note that the {@link Path} class defines the {@link - * Path#newDirectoryStream newDirectoryStream} method to open a directory - * and iterate over the names of the files in the directory. This may use - * less resources when working with very large directories. The {@link - * #toPath toPath} method may be used to obtain a {@code Path} representing - * this abstract pathname. + *
Note that the {@link java.nio.file.Files} class defines the {@link + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method + * to open a directory and iterate over the names of the files in the + * 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. @@ -1154,6 +1170,7 @@ public class File * the directory * * @since 1.2 + * @see java.nio.file.Files#newDirectoryStream(Path,String) */ public File[] listFiles(FilenameFilter filter) { String ss[] = list(); @@ -1191,6 +1208,7 @@ public class File * the directory * * @since 1.2 + * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter) */ public File[] listFiles(FileFilter filter) { String ss[] = list(); @@ -1207,12 +1225,6 @@ public class File /** * Creates the directory named by this abstract pathname. * - *
Note that the {@link Path} class defines the {@link Path#createDirectory
- * createDirectory} method to throw an {@link IOException} when a directory
- * cannot be created. This is useful for error reporting and to diagnose why
- * a directory cannot be created. The {@link #toPath toPath} method may be
- * used to obtain a {@code Path} representing this abstract pathname.
- *
* @return true
if and only if the directory was
* created; false
otherwise
*
@@ -1278,10 +1290,9 @@ public class File
* already exists. The return value should always be checked to make sure
* that the rename operation was successful.
*
- *
Note that the {@link Path} class defines the {@link Path#moveTo - * moveTo} method to move or rename a file in a platform independent manner. - * The {@link #toPath toPath} method may be used to obtain a {@code Path} - * representing this abstract pathname. + *
Note that the {@link java.nio.file.Files} class defines the {@link + * java.nio.file.Files#move move} method to move or rename a file in a + * platform independent manner. * * @param dest The new abstract pathname for the named file * @@ -1369,10 +1380,9 @@ public class File * Sets the owner's or everybody's write permission for this abstract * pathname. * - *
The {@link java.nio.file.attribute.Attributes Attributes} class - * defines methods that operate on file attributes including file - * permissions. This may be used when finer manipulation of file permissions - * is required. + *
The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param writable
* If true
, sets the access permission to allow write
@@ -1437,10 +1447,9 @@ public class File
* Sets the owner's or everybody's read permission for this abstract
* pathname.
*
- *
The {@link java.nio.file.attribute.Attributes Attributes} class - * defines methods that operate on file attributes including file - * permissions. This may be used when finer manipulation of file permissions - * is required. + *
The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param readable
* If true
, sets the access permission to allow read
@@ -1511,10 +1520,9 @@ public class File
* Sets the owner's or everybody's execute permission for this abstract
* pathname.
*
- *
The {@link java.nio.file.attribute.Attributes Attributes} class - * defines methods that operate on file attributes including file - * permissions. This may be used when finer manipulation of file permissions - * is required. + *
The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param executable
* If true
, sets the access permission to allow execute
@@ -1646,6 +1654,7 @@ public class File
* filesystem roots.
*
* @since 1.2
+ * @see java.nio.file.FileStore
*/
public static File[] listRoots() {
return fs.listRoots();
@@ -1753,7 +1762,7 @@ public class File
/* -- Temporary files -- */
- static class TempDirectory {
+ private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
@@ -1880,11 +1889,12 @@ public class File
* java.lang.String, java.io.File)
* createTempFile(prefix, suffix, null)}.
*
- *
The {@link #createTemporaryFile(String,String,FileAttribute[])} method - * provides an alternative method to create an empty file in the - * temporary-file directory. Files created by that method may have more - * restrictive access permissions to files created by this method and so - * may be more suited to security-sensitive applications. + *
The {@link + * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[]) + * Files.createTempFile} method provides an alternative method to create an + * empty file in the temporary-file directory. Files created by that method + * may have more restrictive access permissions to files created by this + * method and so may be more suited to security-sensitive applications. * * @param prefix The prefix string to be used in generating the file's * name; must be at least three characters long @@ -1907,6 +1917,7 @@ public class File * method does not allow a file to be created * * @since 1.2 + * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[]) */ public static File createTempFile(String prefix, String suffix) throws IOException @@ -1914,61 +1925,6 @@ public class File return createTempFile(prefix, suffix, null); } - /** - * Creates an empty file in the default temporary-file directory, using - * the given prefix and suffix to generate its name. - * - *
The {@code attrs} parameter is an optional array of {@link FileAttribute - * attributes} to set atomically when creating the file. Each attribute is - * identified by its {@link FileAttribute#name name}. If more than one attribute - * of the same name is included in the array then all but the last occurrence - * is ignored. - * - *
Where the {@code attrs} parameter does not specify access
- * permissions to set atomically when creating the file, then the
- * resulting file may have more restrictive access permissions than files
- * created by the {@link #createTempFile(java.lang.String, java.lang.String)}
- * method.
- *
- * @param prefix
- * The prefix string to be used in generating the file's
- * name; must be at least three characters long
- * @param suffix
- * The suffix string to be used in generating the file's
- * name; may be {@code null}, in which case the suffix
- * {@code ".tmp"} will be used
- * @param attrs
- * An optional list of file attributes to set atomically when creating
- * the file
- *
- * @return An abstract pathname denoting a newly-created empty file
- *
- * @throws IllegalArgumentException
- * If the {@code prefix} argument contains fewer than three
- * characters
- * @throws UnsupportedOperationException
- * If the array contains an attribute that cannot be set atomically
- * when creating the file
- * @throws IOException
- * If a file could not be created
- * @throws SecurityException
- * If a security manager exists and its {@link
- * java.lang.SecurityManager#checkWrite(java.lang.String)}
- * method does not allow a file to be created.
- *
- * @since 1.7
- */
- public static File createTemporaryFile(String prefix,
- String suffix,
- FileAttribute>... attrs)
- throws IOException
- {
- if (prefix.length() < 3)
- throw new IllegalArgumentException("Prefix string too short");
- suffix = (suffix == null) ? ".tmp" : suffix;
- return TempFileHelper.createFile(prefix, suffix, attrs);
- }
-
/* -- Basic infrastructure -- */
/**
@@ -2104,6 +2060,7 @@ public class File
* path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
*
* @since 1.7
+ * @see Path#toFile
*/
public Path toPath() {
Path result = filePath;
@@ -2111,12 +2068,7 @@ public class File
synchronized (this) {
result = filePath;
if (result == null) {
- if (path.length() == 0) {
- // assume default file system treats "." as current directory
- result = Paths.get(".");
- } else {
- result = Paths.get(path);
- }
+ result = FileSystems.getDefault().getPath(path);
filePath = result;
}
}
diff --git a/src/share/classes/java/io/FileInputStream.java b/src/share/classes/java/io/FileInputStream.java
index 23530c19e1f5433b5a4681f3cdd6bf132a7f211d..da7ad18a5323ef9f0db499c614fc75cbb4c434a0 100644
--- a/src/share/classes/java/io/FileInputStream.java
+++ b/src/share/classes/java/io/FileInputStream.java
@@ -42,6 +42,7 @@ import sun.nio.ch.FileChannelImpl;
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
+ * @see java.nio.file.Files#newInputStream
* @since JDK1.0
*/
public
diff --git a/src/share/classes/java/io/FileOutputStream.java b/src/share/classes/java/io/FileOutputStream.java
index 3fe3a594fd220f5d749ffdfc469df8c4d07f2367..d714679164ad3098c731edcf7ee0160550c28ae7 100644
--- a/src/share/classes/java/io/FileOutputStream.java
+++ b/src/share/classes/java/io/FileOutputStream.java
@@ -46,6 +46,7 @@ import sun.nio.ch.FileChannelImpl;
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileInputStream
+ * @see java.nio.file.Files#newOutputStream
* @since JDK1.0
*/
public
diff --git a/src/share/classes/java/io/FilePermission.java b/src/share/classes/java/io/FilePermission.java
index 06b4f3bb267d823f49b4a9128d82732356fbace0..b5feb367e13ead2ad29c8ab3914428285a07a86c 100644
--- a/src/share/classes/java/io/FilePermission.java
+++ b/src/share/classes/java/io/FilePermission.java
@@ -72,7 +72,7 @@ import sun.security.util.SecurityConstants;
*
diff --git a/src/share/classes/java/io/SerialCallbackContext.java b/src/share/classes/java/io/SerialCallbackContext.java index 90d022e53ea30641187b83f047ac6061a3c54ebf..f62bdbf9a3e4a46a4274a57ed486275bfd822997 100644 --- a/src/share/classes/java/io/SerialCallbackContext.java +++ b/src/share/classes/java/io/SerialCallbackContext.java @@ -54,5 +54,3 @@ thread = null; } } - - diff --git a/src/share/classes/java/nio/channels/FileChannel.java b/src/share/classes/java/nio/channels/FileChannel.java index 8dff4bfc31612c814b596d245217cc34514827eb..80961dd3f8e0df60221e527e8ee5760c278a3ec8 100644 --- a/src/share/classes/java/nio/channels/FileChannel.java +++ b/src/share/classes/java/nio/channels/FileChannel.java @@ -248,7 +248,7 @@ public abstract class FileChannel * FileSystemProvider#newFileChannel newFileChannel} method on the * provider that created the {@code Path}. * - * @param file + * @param path * The path of the file to open or create * @param options * Options specifying how the file is opened @@ -261,7 +261,7 @@ public abstract class FileChannel * @throws IllegalArgumentException * If the set contains an invalid combination of options * @throws UnsupportedOperationException - * If the {@code file} is associated with a provider that does not + * If the {@code path} is associated with a provider that does not * support creating file channels, or an unsupported open option is * specified, or the array contains an attribute that cannot be set * atomically when creating the file @@ -278,13 +278,13 @@ public abstract class FileChannel * * @since 1.7 */ - public static FileChannel open(Path file, + public static FileChannel open(Path path, Set extends OpenOption> options, FileAttribute>... attrs) throws IOException { - FileSystemProvider provider = file.getFileSystem().provider(); - return provider.newFileChannel(file, options, attrs); + FileSystemProvider provider = path.getFileSystem().provider(); + return provider.newFileChannel(path, options, attrs); } private static final FileAttribute>[] NO_ATTRIBUTES = new FileAttribute[0]; @@ -295,10 +295,12 @@ public abstract class FileChannel *
An invocation of this method behaves in exactly the same way as the * invocation *
- * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, options, new FileAttribute<?>[0]); + * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]); *+ * where {@code opts} is a set of the options specified in the {@code + * options} array. * - * @param file + * @param path * The path of the file to open or create * @param options * Options specifying how the file is opened @@ -308,7 +310,7 @@ public abstract class FileChannel * @throws IllegalArgumentException * If the set contains an invalid combination of options * @throws UnsupportedOperationException - * If the {@code file} is associated with a provider that does not + * If the {@code path} is associated with a provider that does not * support creating file channels, or an unsupported open option is * specified * @throws IOException @@ -324,12 +326,12 @@ public abstract class FileChannel * * @since 1.7 */ - public static FileChannel open(Path file, OpenOption... options) + public static FileChannel open(Path path, OpenOption... options) throws IOException { Set
Objects of this type may be used with the {@link + * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)}, + * {@link Files#copy(java.io.InputStream,Path,CopyOption[]) + * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move + * Files.move(Path,Path,CopyOption...)} methods to configure how a file is + * copied or moved. * *
The {@link StandardCopyOption} enumeration type defines the * standard options. diff --git a/src/share/classes/java/nio/file/DirectoryStream.java b/src/share/classes/java/nio/file/DirectoryStream.java index 5601c9d99a8c802fa687e7da92e1cedff753e517..d34f8dbd450781c84385b0dea101581597558eed 100644 --- a/src/share/classes/java/nio/file/DirectoryStream.java +++ b/src/share/classes/java/nio/file/DirectoryStream.java @@ -54,7 +54,7 @@ import java.io.IOException; * construct to ensure that the stream is closed: *
* Path dir = ... - * try (DirectoryStream<Path> stream = dir.newDirectoryStream()) { + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { * for (Path entry: stream) { * ... * } @@ -97,8 +97,8 @@ import java.io.IOException; * both the for-each and try-with-resources constructs. ** - * @param path - * the path string to convert + * @param first + * the path string or initial part of the path string + * @param more + * additional strings to be joined to form the path string * * @return the resulting {@code Path} * @@ -65,8 +80,8 @@ public final class Paths { * * @see FileSystem#getPath */ - public static Path get(String path) { - return FileSystems.getDefault().getPath(path); + public static Path get(String first, String... more) { + return FileSystems.getDefault().getPath(first, more); } /** diff --git a/src/share/classes/java/nio/file/SecureDirectoryStream.java b/src/share/classes/java/nio/file/SecureDirectoryStream.java index 319237bfe9694e9d27885659eefac2b4df43de6c..fa26e513fd990a2e01cd595ef1cf69908cdb7ff0 100644 --- a/src/share/classes/java/nio/file/SecureDirectoryStream.java +++ b/src/share/classes/java/nio/file/SecureDirectoryStream.java @@ -43,7 +43,7 @@ import java.io.IOException; * ** List<Path> listSourceFiles(Path dir) throws IOException { - * List<Path> result = new ArrayList<Path>(); - * try (DirectoryStream<Path> stream = dir.newDirectoryStream("*.{c,h,cpp,hpp,java}")) { + * List<Path> result = new ArrayList<>(); + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) { * for (Path entry: stream) { * result.add(entry); * } @@ -113,7 +113,7 @@ import java.io.IOException; * * @since 1.7 * - * @see Path#newDirectoryStream + * @see Files#newDirectoryStream(Path) */ public interface DirectoryStream* where {@code ':'} stands for itself. * *@@ -122,9 +122,9 @@ public interface DirectoryStream /** * An interface that is implemented by objects that decide if a directory * entry should be accepted or filtered. A {@code Filter} is passed as the - * parameter to the {@link Path#newDirectoryStream(DirectoryStream.Filter) - * newDirectoryStream} method when opening a directory to iterate over the - * entries in the directory. + * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)} + * method when opening a directory to iterate over the entries in the + * directory. * * @param the type of the directory entry * diff --git a/src/share/classes/java/nio/file/FileRef.java b/src/share/classes/java/nio/file/FileRef.java deleted file mode 100644 index fea3b7c3dfe399505b6a931b3c1423e75061774d..0000000000000000000000000000000000000000 --- a/src/share/classes/java/nio/file/FileRef.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.nio.file; - -import java.nio.file.attribute.*; -import java.util.Map; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -/** - * A reference to a file. - * - * A {@code FileRef} is an object that locates a file and defines methods to - * open the file for reading or writing. It also provides access to associated - * metadata or file attributes. - * - * @since 1.7 - * @see java.nio.file.attribute.Attributes - * @see java.io.File#toPath - */ - -public interface FileRef { - - /** - * Opens the file referenced by this object, returning an input stream to - * read from the file. The stream will not be buffered, and is not required - * to support the {@link InputStream#mark mark} or {@link InputStream#reset - * reset} methods. The stream will be safe for access by multiple concurrent - * threads. Reading commences at the beginning of the file. - * - *
The {@code options} parameter determines how the file is opened. - * If no options are present then it is equivalent to opening the file with - * the {@link StandardOpenOption#READ READ} option. In addition to the {@code - * READ} option, an implementation may also support additional implementation - * specific options. - * - * @return an input stream to read bytes from the file - * - * @throws IllegalArgumentException - * if an invalid combination of options is specified - * @throws UnsupportedOperationException - * if an unsupported option is specified - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the file. - */ - InputStream newInputStream(OpenOption... options) throws IOException; - - /** - * Opens or creates the file located by this object for writing, returning - * an output stream to write bytes to the file. - * - *
The {@code options} parameter determines how the file is opened. - * If no options are present then this method creates a new file for writing - * or truncates an existing file. In addition to the {@link StandardOpenOption - * standard} options, an implementation may also support additional - * implementation specific options. - * - *
The resulting stream will not be buffered. The stream will be safe - * for access by multiple concurrent threads. - * - * @param options - * options specifying how the file is opened - * - * @return a new output stream - * - * @throws IllegalArgumentException - * if {@code options} contains an invalid combination of options - * @throws UnsupportedOperationException - * if an unsupported option is specified - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked to check write access to the file. - */ - OutputStream newOutputStream(OpenOption... options) throws IOException; - - /** - * Returns a file attribute view of a given type. - * - *
A file attribute view provides a read-only or updatable view of a - * set of file attributes. This method is intended to be used where the file - * attribute view defines type-safe methods to read or update the file - * attributes. The {@code type} parameter is the type of the attribute view - * required and the method returns an instance of that type if supported. - * The {@link BasicFileAttributeView} type supports access to the basic - * attributes of a file. Invoking this method to select a file attribute - * view of that type will always return an instance of that class. - * - *
The {@code options} array may be used to indicate how symbolic links - * are handled by the resulting file attribute view for the case that the - * file is a symbolic link. By default, symbolic links are followed. If the - * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then - * symbolic links are not followed. This option is ignored by implementations - * that do not support symbolic links. - * - * @param type - * the {@code Class} object corresponding to the file attribute view - * @param options - * options indicating how symbolic links are handled - * - * @return a file attribute view of the specified type, or {@code null} if - * the attribute view type is not available - * - * @throws UnsupportedOperationException - * If options contains an unsupported option. This exception is - * specified to allow the {@code LinkOption} enum be extended - * in future releases. - * - * @see Attributes#readBasicFileAttributes - */ -
V getFileAttributeView(Class type, - LinkOption... options); - - /** - * Sets the value of a file attribute. - * - * The {@code attribute} parameter identifies the attribute to be set - * and takes the form: - *
- * [view-name:]attribute-name - *- * where square brackets [...] delineate an optional component and the - * character {@code ':'} stands for itself. - * - *view-name is the {@link FileAttributeView#name name} of a {@link - * FileAttributeView} that identifies a set of file attributes. If not - * specified then it defaults to {@code "basic"}, the name of the file - * attribute view that identifies the basic set of file attributes common to - * many file systems. attribute-name is the name of the attribute - * within the set. - * - *
Usage Example: - * Suppose we want to set the DOS "hidden" attribute: - *
- * file.setAttribute("dos:hidden", true); - *- * - * @param attribute - * the attribute to set - * @param value - * the attribute value - * @param options - * options indicating how symbolic links are handled - * - * @throws UnsupportedOperationException - * if the attribute view is not available or it does not support - * updating the attribute - * @throws IllegalArgumentException - * if the attribute value is of the correct type but has an - * inappropriate value - * @throws ClassCastException - * If the attribute value is not of the expected type or is a - * collection containing elements that are not of the expected - * type - * @throws IOException - * If an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, its {@link SecurityManager#checkWrite(String) checkWrite} - * method denies write access to the file. If this method is invoked - * to set security sensitive attributes then the security manager - * may be invoked to check for additional permissions. - */ - void setAttribute(String attribute, Object value, LinkOption... options) - throws IOException; - - /** - * Reads the value of a file attribute. - * - *The {@code attribute} parameter identifies the attribute to be read - * and takes the form: - *
- * [view-name:]attribute-name - *- * where square brackets [...] delineate an optional component and the - * character {@code ':'} stands for itself. - * - *view-name is the {@link FileAttributeView#name name} of a {@link - * FileAttributeView} that identifies a set of file attributes. If not - * specified then it defaults to {@code "basic"}, the name of the file - * attribute view that identifies the basic set of file attributes common to - * many file systems. attribute-name is the name of the attribute. - * - *
The {@code options} array may be used to indicate how symbolic links - * are handled for the case that the file is a symbolic link. By default, - * symbolic links are followed and the file attribute of the final target - * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS - * NOFOLLOW_LINKS} is present then symbolic links are not followed and so - * the method returns the file attribute of the symbolic link. - * - *
Usage Example: - * Suppose we require the user ID of the file owner on a system that - * supports a "{@code unix}" view: - *
- * int uid = (Integer)file.getAttribute("unix:uid"); - *- * - * @param attribute - * the attribute to read - * @param options - * options indicating how symbolic links are handled - * @return the attribute value or {@code null} if the attribute view - * is not available or it does not support reading the attribute - * - * reading the attribute - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, its {@link SecurityManager#checkRead(String) checkRead} - * method denies read access to the file. If this method is invoked - * to read security sensitive attributes then the security manager - * may be invoked to check for additional permissions. - */ - Object getAttribute(String attribute, LinkOption... options) throws IOException; - - /** - * Reads a set of file attributes as a bulk operation. - * - *The {@code attributes} parameter identifies the attributes to be read - * and takes the form: - *
- * [view-name:]attribute-list - *- * where square brackets [...] delineate an optional component and the - * character {@code ':'} stands for itself. - * - *view-name is the {@link FileAttributeView#name name} of a {@link - * FileAttributeView} that identifies a set of file attributes. If not - * specified then it defaults to {@code "basic"}, the name of the file - * attribute view that identifies the basic set of file attributes common to - * many file systems. - * - *
The attribute-list component is a comma separated list of - * zero or more names of attributes to read. If the list contains the value - * {@code "*"} then all attributes are read. Attributes that are not supported - * are ignored and will not be present in the returned map. It is - * implementation specific if all attributes are read as an atomic operation - * with respect to other file system operations. - * - *
The following examples demonstrate possible values for the {@code - * attributes} parameter: - * - *
- *- * - *- *
- *- * - *{@code "*"} - *Read all {@link BasicFileAttributes basic-file-attributes}. - *- * - *{@code "size,lastModifiedTime,lastAccessTime"} - *Reads the file size, last modified time, and last access time - * attributes. - *- * - *{@code "posix:*"} - *Read all {@link PosixFileAttributes POSIX-file-attributes}.. - *- * - *{@code "posix:permissions,owner,size"} - *Reads the POSX file permissions, owner, and file size. - *The {@code options} array may be used to indicate how symbolic links - * are handled for the case that the file is a symbolic link. By default, - * symbolic links are followed and the file attribute of the final target - * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS - * NOFOLLOW_LINKS} is present then symbolic links are not followed and so - * the method returns the file attribute of the symbolic link. - * - * @param attributes - * The attributes to read - * @param options - * Options indicating how symbolic links are handled - * - * @return A map of the attributes returned; may be empty. The map's keys - * are the attribute names, its values are the attribute values - * - * @throws IOException - * If an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, its {@link SecurityManager#checkRead(String) checkRead} - * method denies read access to the file. If this method is invoked - * to read security sensitive attributes then the security manager - * may be invoke to check for additional permissions. - */ - Map
readAttributes(String attributes, LinkOption... options) - throws IOException; -} diff --git a/src/share/classes/java/nio/file/FileStore.java b/src/share/classes/java/nio/file/FileStore.java index 4a79cccdff5fbbea6e4b1e4e2cfe15749bc8f5cb..4284a8ad5e9fc43694a71880d74f4871e77bf5ce 100644 --- a/src/share/classes/java/nio/file/FileStore.java +++ b/src/share/classes/java/nio/file/FileStore.java @@ -32,16 +32,13 @@ import java.io.IOException; * Storage for files. A {@code FileStore} represents a storage pool, device, * partition, volume, concrete file system or other implementation specific means * of file storage. The {@code FileStore} for where a file is stored is obtained - * by invoking the {@link Path#getFileStore getFileStore} method, or all file + * by invoking the {@link Files#getFileStore getFileStore} method, or all file * stores can be enumerated by invoking the {@link FileSystem#getFileStores * getFileStores} method. * * In addition to the methods defined by this class, a file store may support * one or more {@link FileStoreAttributeView FileStoreAttributeView} classes * that provide a read-only or updatable view of a set of file store attributes. - * File stores associated with the default provider support the {@link - * FileStoreSpaceAttributeView} to read the space related attributes of the - * file store. * * @since 1.7 */ @@ -86,6 +83,51 @@ public abstract class FileStore { */ public abstract boolean isReadOnly(); + /** + * Returns the size, in bytes, of the file store. + * + * @return the size of the file store, in bytes + * + * @throws IOException + * if an I/O error occurs + */ + public abstract long getTotalSpace() throws IOException; + + /** + * Returns the number of bytes available to this Java virtual machine on the + * file store. + * + *
The returned number of available bytes is a hint, but not a + * guarantee, that it is possible to use most or any of these bytes. The + * number of usable bytes is most likely to be accurate immediately + * after the space attributes are obtained. It is likely to be made inaccurate + * by any external I/O operations including those made on the system outside + * of this Java virtual machine. + * + * @return the number of bytes available + * + * @throws IOException + * if an I/O error occurs + */ + public abstract long getUsableSpace() throws IOException; + + /** + * Returns the number of unallocated bytes in the file store. + * + *
The returned number of unallocated bytes is a hint, but not a + * guarantee, that it is possible to use most or any of these bytes. The + * number of unallocated bytes is most likely to be accurate immediately + * after the space attributes are obtained. It is likely to be + * made inaccurate by any external I/O operations including those made on + * the system outside of this virtual machine. + * + * @return the number of unallocated bytes + * + * @throws IOException + * if an I/O error occurs + */ + public abstract long getUnallocatedSpace() throws IOException; + /** * Tells whether or not this file store supports the file attributes * identified by the given file attribute view. @@ -131,12 +173,6 @@ public abstract class FileStore { * The {@code type} parameter is the type of the attribute view required and * the method returns an instance of that type if supported. * - *
For {@code FileStore} objects created by the default provider, then - * the file stores support the {@link FileStoreSpaceAttributeView} that - * provides access to space attributes. In that case invoking this method - * with a parameter value of {@code FileStoreSpaceAttributeView.class} will - * always return an instance of that class. - * * @param type * the {@code Class} object corresponding to the attribute view * @@ -160,10 +196,6 @@ public abstract class FileStore { * a {@link FileStore AttributeView} that identifies a set of file attributes. * attribute-name is the name of the attribute. * - *
For {@code FileStore} objects created by the default provider, then - * the file stores support the {@link FileStoreSpaceAttributeView} that - * provides access to space attributes. - * *
Usage Example: * Suppose we want to know if ZFS compression is enabled (assuming the "zfs" * view is supported): diff --git a/src/share/classes/java/nio/file/FileSystem.java b/src/share/classes/java/nio/file/FileSystem.java index 8c7637a3947ae4431d96945d2dee873476de9f06..15b6ca2cd0fd0ebd3af38b380edb61414a223b50 100644 --- a/src/share/classes/java/nio/file/FileSystem.java +++ b/src/share/classes/java/nio/file/FileSystem.java @@ -38,8 +38,8 @@ import java.io.IOException; *
The default file system, obtained by invoking the {@link FileSystems#getDefault * FileSystems.getDefault} method, provides access to the file system that is * accessible to the Java virtual machine. The {@link FileSystems} class defines - * methods to create file systems that provide access to other types of file - * systems. + * methods to create file systems that provide access to other types of (custom) + * file systems. * *
A file system is the factory for several types of objects: * @@ -214,10 +214,9 @@ public abstract class FileSystem * Suppose we want to print the space usage for all file stores: *
* for (FileStore store: FileSystems.getDefault().getFileStores()) { - * FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store); - * long total = attrs.totalSpace() / 1024; - * long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / 1024; - * long avail = attrs.usableSpace() / 1024; + * long total = store.getTotalSpace() / 1024; + * long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024; + * long avail = store.getUsableSpace() / 1024; * System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail); * } *@@ -244,7 +243,20 @@ public abstract class FileSystem public abstract SetsupportedFileAttributeViews(); /** - * Converts a path string to a {@code Path}. + * Converts a path string, or a sequence of strings that when joined form + * a path string, to a {@code Path}. If {@code more} does not specify any + * elements then the value of the {@code first} parameter is the path string + * to convert. If {@code more} specifies one or more elements then each + * non-empty string, including {@code first}, is considered to be a sequence + * of name elements (see {@link Path}) and is joined to form a path string. + * The details as to how the Strings are joined is provider specific but + * typically they will be joined using the {@link #getSeparator + * name-separator} as the separator. For example, if the name separator is + * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the + * path string {@code "/foo/bar/gus"} is converted to a {@code Path}. + * A {@code Path} representing an empty path is returned if {@code first} + * is the empty string and {@code more} does not contain any non-empty + * strings. * * The parsing and conversion to a path object is inherently * implementation dependent. In the simplest case, the path string is rejected, @@ -270,18 +282,17 @@ public abstract class FileSystem * index} value indicating the first position in the {@code path} parameter * that caused the path string to be rejected. * - *
Invoking this method with an empty path string throws - * {@code InvalidPathException}. + * @param first + * the path string or initial part of the path string + * @param more + * additional strings to be joined to form the path string * - * @param path - * The path string - * - * @return A {@code Path} object + * @return the resulting {@code Path} * * @throws InvalidPathException * If the path string cannot be converted */ - public abstract Path getPath(String path); + public abstract Path getPath(String first, String... more); /** * Returns a {@code PathMatcher} that performs match operations on the @@ -290,9 +301,9 @@ public abstract class FileSystem * * The {@code syntaxAndPattern} parameter identifies the syntax and the * pattern and takes the form: - *
+ *+ ** syntax:pattern - *A {@code FileSystem} implementation supports the "{@code glob}" and @@ -409,7 +420,7 @@ public abstract class FileSystem * @throws UnsupportedOperationException * If the pattern syntax is not known to the implementation * - * @see Path#newDirectoryStream(String) + * @see Files#newDirectoryStream(Path,String) */ public abstract PathMatcher getPathMatcher(String syntaxAndPattern); @@ -421,10 +432,8 @@ public abstract class FileSystem *
Usage Example: * Suppose we want to make "joe" the owner of a file: *
- * Path file = ... - * UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService() - * .lookupPrincipalByName("joe"); - * Attributes.setOwner(file, joe); + * UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService(); + * Files.setOwner(path, lookupService.lookupPrincipalByName("joe")); ** * @throws UnsupportedOperationException diff --git a/src/share/classes/java/nio/file/FileSystems.java b/src/share/classes/java/nio/file/FileSystems.java index 3fc348b09f4d58b6e6d0cb9094fb242b33091857..3d7ab7a20f196b32f465c0f54433f86b43c54d33 100644 --- a/src/share/classes/java/nio/file/FileSystems.java +++ b/src/share/classes/java/nio/file/FileSystems.java @@ -164,8 +164,8 @@ public final class FileSystems { * to the first provider instance. The third provider class is instantiated * by invoking it with a reference to the second instance, and so on. The * last provider to be instantiated becomes the default provider; its {@code - * getFileSystem} method is invoked with the URI {@code "file:///"} to create - * the default file system. + * getFileSystem} method is invoked with the URI {@code "file:///"} to + * get a reference to the default file system. * *Subsequent invocations of this method return the file system that was * returned by the first invocation. @@ -238,7 +238,7 @@ public final class FileSystems { * Suppose there is a provider identified by the scheme {@code "memory"} * installed: *
- * Map<String,String> env = new HashMap<String,String>(); + * Map<String,String> env = new HashMap<>(); * env.put("capacity", "16G"); * env.put("blockSize", "4k"); * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env); @@ -343,33 +343,25 @@ public final class FileSystems { * *@@ -72,10 +73,12 @@ import java.io.IOException; * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) * throws IOException * { + * Path targetdir = target.resolve(source.relativize(dir)); * try { - * dir.copyTo(target.resolve(source.relativize(dir))); + * Files.copy(dir, targetdir); * } catch (FileAlreadyExistsException e) { - * // ignore + * if (!Files.isDirectory(targetdir)) + * throw e; * } * return CONTINUE; * } @@ -83,7 +86,7 @@ import java.io.IOException; * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) * throws IOException * { - * file.copyTo(target.resolve(source.relativize(file))); + * Files.copy(file, target.resolve(source.relativize(file))); * return CONTINUE; * } * }); diff --git a/src/share/classes/java/nio/file/Files.java b/src/share/classes/java/nio/file/Files.java index a0f00855b7463852a08a7febc0fd0e0871a05df9..cb1fde29685aaa99bebbc33cbb7c82b4212af558 100644 --- a/src/share/classes/java/nio/file/Files.java +++ b/src/share/classes/java/nio/file/Files.java @@ -25,16 +25,32 @@ package java.nio.file; -import java.nio.file.spi.FileTypeDetector; import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.spi.FileTypeDetector; +import java.nio.channels.SeekableByteChannel; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.IOException; import java.util.*; import java.security.AccessController; import java.security.PrivilegedAction; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; /** - * This class consists exclusively of static methods that operate on files or - * directories. + * This class consists exclusively of static methods that operate on files, + * directories, or other types of files. + * + *This method makes use of specialized providers that create pseudo file * systems where the contents of one or more files is treated as a file - * system. The {@code file} parameter is a reference to an existing file - * and the {@code env} parameter is a map of provider specific properties to - * configure the file system. + * system. * *
This method iterates over the {@link FileSystemProvider#installedProviders() * installed} providers. It invokes, in turn, each provider's {@link - * FileSystemProvider#newFileSystem(FileRef,Map) newFileSystem(FileRef,Map)} method. - * If a provider returns a file system then the iteration terminates - * and the file system is returned. If none of the installed providers return - * a {@code FileSystem} then an attempt is made to locate the provider using - * the given class loader. If a provider returns a file system then the lookup - * terminates and the file system is returned. + * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method + * with an empty map. If a provider returns a file system then the iteration + * terminates and the file system is returned. If none of the installed + * providers return a {@code FileSystem} then an attempt is made to locate + * the provider using the given class loader. If a provider returns a file + * system then the lookup terminates and the file system is returned. * - * @param file - * a reference to a file - * @param env - * a map of provider specific properties to configure the file system; - * may be empty + * @param path + * the path to the file * @param loader * the class loader to locate the provider or {@code null} to only * attempt to locate an installed provider * * @return a new file system * - * @throws IllegalArgumentException - * if the {@code env} parameter does not contain properties required - * by the provider, or a property value is invalid * @throws ProviderNotFoundException * if a provider supporting this file type cannot be located * @throws ServiceConfigurationError @@ -380,18 +372,18 @@ public final class FileSystems { * if a security manager is installed and it denies an unspecified * permission */ - public static FileSystem newFileSystem(FileRef file, - Map
env, + public static FileSystem newFileSystem(Path path, ClassLoader loader) throws IOException { - if (file == null) + if (path == null) throw new NullPointerException(); + Map env = Collections.emptyMap(); // check installed providers for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { try { - return provider.newFileSystem(file, env); + return provider.newFileSystem(path, env); } catch (UnsupportedOperationException uoe) { } } @@ -402,7 +394,7 @@ public final class FileSystems { .load(FileSystemProvider.class, loader); for (FileSystemProvider provider: sl) { try { - return provider.newFileSystem(file, env); + return provider.newFileSystem(path, env); } catch (UnsupportedOperationException uoe) { } } diff --git a/src/share/classes/java/nio/file/FileTreeWalker.java b/src/share/classes/java/nio/file/FileTreeWalker.java index b3f422e6ac0ff03dc92ba4acfce5dbeaf0b5423f..fb3995315ccb853ba1cb0e58fbedd748e5540c3e 100644 --- a/src/share/classes/java/nio/file/FileTreeWalker.java +++ b/src/share/classes/java/nio/file/FileTreeWalker.java @@ -69,7 +69,8 @@ class FileTreeWalker { FileVisitResult result = walk(start, 0, new ArrayList ()); - Objects.nonNull(result, "FileVisitor returned null"); + if (result == null) + throw new NullPointerException("FileVisitor returned null"); } /** @@ -102,12 +103,13 @@ class FileTreeWalker { if (attrs == null) { try { try { - attrs = Attributes.readBasicFileAttributes(file, linkOptions); + attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions); } catch (IOException x1) { if (followLinks) { try { - attrs = Attributes - .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS); + attrs = Files.readAttributes(file, + BasicFileAttributes.class, + LinkOption.NOFOLLOW_LINKS); } catch (IOException x2) { exc = x2; } @@ -151,7 +153,7 @@ class FileTreeWalker { } else { boolean isSameFile = false; try { - isSameFile = file.isSameFile(ancestor.file()); + isSameFile = Files.isSameFile(file, ancestor.file()); } catch (IOException x) { // ignore } catch (SecurityException x) { @@ -175,7 +177,7 @@ class FileTreeWalker { // open the directory try { - stream = file.newDirectoryStream(); + stream = Files.newDirectoryStream(file); } catch (IOException x) { return visitor.visitFileFailed(file, x); } catch (SecurityException x) { @@ -212,7 +214,11 @@ class FileTreeWalker { } finally { try { stream.close(); - } catch (IOException x) { } + } catch (IOException e) { + // IOException will be notified to postVisitDirectory + if (ioe == null) + ioe = e; + } } // invoke postVisitDirectory last diff --git a/src/share/classes/java/nio/file/FileVisitor.java b/src/share/classes/java/nio/file/FileVisitor.java index bd6bac15d59eee9ce63aade3bca717587b70b651..3c507a8d443b89700c372c01063089dd15161ed5 100644 --- a/src/share/classes/java/nio/file/FileVisitor.java +++ b/src/share/classes/java/nio/file/FileVisitor.java @@ -30,8 +30,8 @@ import java.io.IOException; /** * A visitor of files. An implementation of this interface is provided to the - * {@link Files#walkFileTree walkFileTree} utility method to visit each file - * in a tree. + * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in + * a file tree. * * Usage Examples: * Suppose we want to delete a file tree. In that case, each directory should @@ -43,19 +43,20 @@ import java.io.IOException; * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) * throws IOException * { - * file.delete(); + * Files.delete(file); * return FileVisitResult.CONTINUE; * } * @Override * public FileVisitResult postVisitDirectory(Path dir, IOException e) * throws IOException * { - * if (e != null) { + * if (e == null) { + * Files.delete(dir); + * return FileVisitResult.CONTINUE; + * } else { * // directory iteration failed * throw e; * } - * dir.delete(); - * return FileVisitResult.CONTINUE; * } * }); *
In most cases, the methods defined here will delegate to the associated + * file system provider to perform the file operations. * * @since 1.7 */ @@ -42,91 +58,2420 @@ import java.security.PrivilegedAction; public final class Files { private Files() { } - // lazy loading of default and installed file type detectors - private static class DefaultFileTypeDetectorHolder { - static final FileTypeDetector defaultFileTypeDetector = - sun.nio.fs.DefaultFileTypeDetector.create(); - static final List
installeDetectors = - loadInstalledDetectors(); + /** + * Returns the {@code FileSystemProvider} to delegate to. + */ + private static FileSystemProvider provider(Path path) { + return path.getFileSystem().provider(); + } - // loads all installed file type detectors - private static List loadInstalledDetectors() { - return AccessController - .doPrivileged(new PrivilegedAction >() { - @Override public List
run() { - List list = new ArrayList (); - ServiceLoader loader = ServiceLoader - .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader()); - for (FileTypeDetector detector: loader) { - list.add(detector); - } - return list; - }}); + // -- File contents -- + + /** + * Opens a file, returning an input stream to read from the file. The stream + * will not be buffered, and is not required to support the {@link + * InputStream#mark mark} or {@link InputStream#reset reset} methods. The + * stream will be safe for access by multiple concurrent threads. Reading + * commences at the beginning of the file. Whether the returned stream is + * asynchronously closeable and/or interruptible is highly + * file system provider specific and therefore not specified. + * + * The {@code options} parameter determines how the file is opened. + * If no options are present then it is equivalent to opening the file with + * the {@link StandardOpenOption#READ READ} option. In addition to the {@code + * READ} option, an implementation may also support additional implementation + * specific options. + * + * @param path + * the path to the file to open + * @param options + * options specifying how the file is opened + * + * @return a new input stream + * + * @throws IllegalArgumentException + * if an invalid combination of options is specified + * @throws UnsupportedOperationException + * if an unsupported option is specified + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + */ + public static InputStream newInputStream(Path path, OpenOption... options) + throws IOException + { + return provider(path).newInputStream(path, options); + } + + /** + * Opens or creates a file, returning an output stream that may be used to + * write bytes to the file. The resulting stream will not be buffered. The + * stream will be safe for access by multiple concurrent threads. Whether + * the returned stream is asynchronously closeable and/or + * interruptible is highly file system provider specific and + * therefore not specified. + * + *
This method opens or creates a file in exactly the manner specified + * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel} + * method with the exception that the {@link StandardOpenOption#READ READ} + * option may not be present in the array of options. If no options are + * present then this method works as if the {@link StandardOpenOption#CREATE + * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, + * and {@link StandardOpenOption#WRITE WRITE} options are present. In other + * words, it opens the file for writing, creating the file if it doesn't + * exist, or initially truncating an existing {@link #isRegularFile + * regular-file} to a size of {@code 0} if it exists. + * + *
Usage Examples: + *
+ * Path path = ... + * + * // replace an existing file or create the file if it doesn't initially exist + * OutputStream out = Files.newOutputStream(path); + * + * // append to an existing file, fail if the file does not exist + * out = Files.newOutputStream(path, APPEND); + * + * // append to an existing file, create file if it doesn't initially exist + * out = Files.newOutputStream(CREATE, APPEND); + * + * // always create new file, failing if it already exists + * out = Files.newOutputStream(CREATE_NEW); + *+ * + * @param path + * the path to the file to open or create + * @param options + * options specifying how the file is opened + * + * @return a new output stream + * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options + * @throws UnsupportedOperationException + * if an unsupported option is specified + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. The {@link + * SecurityManager#checkDelete(String) checkDelete} method is + * invoked to check delete access if the file is opened with the + * {@code DELETE_ON_CLOSE} option. + */ + public static OutputStream newOutputStream(Path path, OpenOption... options) + throws IOException + { + return provider(path).newOutputStream(path, options); + } + + /** + * Opens or creates a file, returning a seekable byte channel to access the + * file. + * + *The {@code options} parameter determines how the file is opened. + * The {@link StandardOpenOption#READ READ} and {@link + * StandardOpenOption#WRITE WRITE} options determine if the file should be + * opened for reading and/or writing. If neither option (or the {@link + * StandardOpenOption#APPEND APPEND} option) is present then the file is + * opened for reading. By default reading or writing commence at the + * beginning of the file. + * + *
In the addition to {@code READ} and {@code WRITE}, the following + * options may be present: + * + *
+ *
+ * + *+ * Option Description + * + *{@link StandardOpenOption#APPEND APPEND} + *If this option is present then the file is opened for writing and + * each invocation of the channel's {@code write} method first advances + * the position to the end of the file and then writes the requested + * data. Whether the advancement of the position and the writing of the + * data are done in a single atomic operation is system-dependent and + * therefore unspecified. This option may not be used in conjunction + * with the {@code READ} or {@code TRUNCATE_EXISTING} options. + *+ * + *{@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} + *If this option is present then the existing file is truncated to + * a size of 0 bytes. This option is ignored when the file is opened only + * for reading. + *+ * + *{@link StandardOpenOption#CREATE_NEW CREATE_NEW} + *If this option is present then a new file is created, failing if + * the file already exists or is a symbolic link. When creating a file the + * check for the existence of the file and the creation of the file if it + * does not exist is atomic with respect to other file system operations. + * This option is ignored when the file is opened only for reading. + *+ * + *{@link StandardOpenOption#CREATE CREATE} + *If this option is present then an existing file is opened if it + * exists, otherwise a new file is created. This option is ignored if the + * {@code CREATE_NEW} option is also present or the file is opened only + * for reading. + *+ * + *{@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} + *When this option is present then the implementation makes a + * best effort attempt to delete the file when closed by the + * {@link SeekableByteChannel#close close} method. If the {@code close} + * method is not invoked then a best effort attempt is made to + * delete the file when the Java virtual machine terminates. + *+ * + *{@link StandardOpenOption#SPARSE SPARSE} + *When creating a new file this option is a hint that the + * new file will be sparse. This option is ignored when not creating + * a new file. + *+ * {@link StandardOpenOption#SYNC SYNC} + *Requires that every update to the file's content or metadata be + * written synchronously to the underlying storage device. (see Synchronized I/O file + * integrity). + *+ * + * + *{@link StandardOpenOption#DSYNC DSYNC} + *Requires that every update to the file's content be written + * synchronously to the underlying storage device. (see Synchronized I/O file + * integrity). + *An implementation may also support additional implementation specific + * options. + * + *
The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when a new file is created. + * + *
In the case of the default provider, the returned seekable byte channel + * is a {@link java.nio.channels.FileChannel}. + * + *
Usage Examples: + *
+ * Path path = ... + * + * // open file for reading + * ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ))); + * + * // open file for writing to the end of an existing file, creating + * // the file if it doesn't already exist + * WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND)); + * + * // create file with initial permissions, opening it for both reading and writing + * {@code FileAttribute<+ * + * @param path + * the path to the file to open or create + * @param options + * options specifying how the file is opened + * @param attrs + * an optional list of file attributes to set atomically when + * creating the file + * + * @return a new seekable byte channel + * + * @throws IllegalArgumentException + * if the set contains an invalid combination of options + * @throws UnsupportedOperationException + * if an unsupported open option is specified or the array contains + * attributes that cannot be set atomically when creating the file + * @throws FileAlreadyExistsException + * if a file of that name already exists and the {@link + * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified + * (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the path if the file is + * opened for reading. The {@link SecurityManager#checkWrite(String) + * checkWrite} method is invoked to check write access to the path + * if the file is opened for writing. The {@link + * SecurityManager#checkDelete(String) checkDelete} method is + * invoked to check delete access if the file is opened with the + * {@code DELETE_ON_CLOSE} option. + * + * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[]) + */ + public static SeekableByteChannel newByteChannel(Path path, + Set extends OpenOption> options, + FileAttribute>... attrs) + throws IOException + { + return provider(path).newByteChannel(path, options, attrs); + } + + /** + * Opens or creates a file, returning a seekable byte channel to access the + * file. + * + *> perms = ...} + * SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms); + * This method opens or creates a file in exactly the manner specified + * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel} + * method. + * + * @param path + * the path to the file to open or create + * @param options + * options specifying how the file is opened + * + * @return a new seekable byte channel + * + * @throws IllegalArgumentException + * if the set contains an invalid combination of options + * @throws UnsupportedOperationException + * if an unsupported open option is specified + * @throws FileAlreadyExistsException + * if a file of that name already exists and the {@link + * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified + * (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the path if the file is + * opened for reading. The {@link SecurityManager#checkWrite(String) + * checkWrite} method is invoked to check write access to the path + * if the file is opened for writing. The {@link + * SecurityManager#checkDelete(String) checkDelete} method is + * invoked to check delete access if the file is opened with the + * {@code DELETE_ON_CLOSE} option. + * + * @see java.nio.channels.FileChannel#open(Path,OpenOption[]) + */ + public static SeekableByteChannel newByteChannel(Path path, OpenOption... options) + throws IOException + { + Set
set = new HashSet (options.length); + Collections.addAll(set, options); + return newByteChannel(path, set); + } + + // -- Directories -- + + /** + * Opens a directory, returning a {@link DirectoryStream} to iterate over + * all entries in the directory. The elements returned by the directory + * stream's {@link DirectoryStream#iterator iterator} are of type {@code + * Path}, each one representing an entry in the directory. The {@code Path} + * objects are obtained as if by {@link Path#resolve(Path) resolving} the + * name of the directory entry against {@code dir}. + * + * When not using the try-with-resources construct, then directory + * stream's {@code close} method should be invoked after iteration is + * completed so as to free any resources held for the open directory. + * + *
When an implementation supports operations on entries in the + * directory that execute in a race-free manner then the returned directory + * stream is a {@link SecureDirectoryStream}. + * + * @param dir + * the path to the directory + * + * @return a new and open {@code DirectoryStream} object + * + * @throws NotDirectoryException + * if the file could not otherwise be opened because it is not + * a directory (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the directory. + */ + public static DirectoryStream
newDirectoryStream(Path dir) + throws IOException + { + return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter () { + @Override + public boolean accept(Path entry) { + return true; + } + }); + } + + /** + * Opens a directory, returning a {@link DirectoryStream} to iterate over + * the entries in the directory. The elements returned by the directory + * stream's {@link DirectoryStream#iterator iterator} are of type {@code + * Path}, each one representing an entry in the directory. The {@code Path} + * objects are obtained as if by {@link Path#resolve(Path) resolving} the + * name of the directory entry against {@code dir}. The entries returned by + * the iterator are filtered by matching the {@code String} representation + * of their file names against the given globbing pattern. + * + * For example, suppose we want to iterate over the files ending with + * ".java" in a directory: + *
+ * Path dir = ... + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.java")) { + * : + * } + *+ * + *The globbing pattern is specified by the {@link + * FileSystem#getPathMatcher getPathMatcher} method. + * + *
When not using the try-with-resources construct, then directory + * stream's {@code close} method should be invoked after iteration is + * completed so as to free any resources held for the open directory. + * + *
When an implementation supports operations on entries in the + * directory that execute in a race-free manner then the returned directory + * stream is a {@link SecureDirectoryStream}. + * + * @param dir + * the path to the directory + * @param glob + * the glob pattern + * + * @return a new and open {@code DirectoryStream} object + * + * @throws java.util.regex.PatternSyntaxException + * if the pattern is invalid + * @throws NotDirectoryException + * if the file could not otherwise be opened because it is not + * a directory (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the directory. + */ + public static DirectoryStream
newDirectoryStream(Path dir, String glob) + throws IOException + { + // avoid creating a matcher if all entries are required. + if (glob.equals("*")) + return newDirectoryStream(dir); + + // create a matcher and return a filter that uses it. + FileSystem fs = dir.getFileSystem(); + final PathMatcher matcher = fs.getPathMatcher("glob:" + glob); + DirectoryStream.Filter filter = new DirectoryStream.Filter () { + @Override + public boolean accept(Path entry) { + return matcher.matches(entry.getFileName()); + } + }; + return fs.provider().newDirectoryStream(dir, filter); + } + + /** + * Opens a directory, returning a {@link DirectoryStream} to iterate over + * the entries in the directory. The elements returned by the directory + * stream's {@link DirectoryStream#iterator iterator} are of type {@code + * Path}, each one representing an entry in the directory. The {@code Path} + * objects are obtained as if by {@link Path#resolve(Path) resolving} the + * name of the directory entry against {@code dir}. The entries returned by + * the iterator are filtered by the given {@link DirectoryStream.Filter + * filter}. + * + * When not using the try-with-resources construct, then directory + * stream's {@code close} method should be invoked after iteration is + * completed so as to free any resources held for the open directory. + * + *
Where the filter terminates due to an uncaught error or runtime + * exception then it is propagated to the {@link Iterator#hasNext() + * hasNext} or {@link Iterator#next() next} method. Where an {@code + * IOException} is thrown, it results in the {@code hasNext} or {@code + * next} method throwing a {@link DirectoryIteratorException} with the + * {@code IOException} as the cause. + * + *
When an implementation supports operations on entries in the + * directory that execute in a race-free manner then the returned directory + * stream is a {@link SecureDirectoryStream}. + * + *
Usage Example: + * Suppose we want to iterate over the files in a directory that are + * larger than 8K. + *
+ * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { + * public boolean accept(Path file) throws IOException { + * return (Files.size(file) > 8192L); + * } + * }; + * Path dir = ... + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { + * : + * } + *+ * + * @param dir + * the path to the directory + * @param filter + * the directory stream filter + * + * @return a new and open {@code DirectoryStream} object + * + * @throws NotDirectoryException + * if the file could not otherwise be opened because it is not + * a directory (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the directory. + */ + public static DirectoryStreamnewDirectoryStream(Path dir, + DirectoryStream.Filter super Path> filter) + throws IOException + { + return provider(dir).newDirectoryStream(dir, filter); + } + + // -- Creation and deletion -- + + /** + * Creates a new and empty file, failing if the file already exists. The + * check for the existence of the file and the creation of the new file if + * it does not exist are a single operation that is atomic with respect to + * all other filesystem activities that might affect the directory. + * + * The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when creating the file. Each attribute + * is identified by its {@link FileAttribute#name name}. If more than one + * attribute of the same name is included in the array then all but the last + * occurrence is ignored. + * + * @param path + * the path to the file to create + * @param attrs + * an optional list of file attributes to set atomically when + * creating the file + * + * @return the file + * + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the file + * @throws FileAlreadyExistsException + * if a file of that name already exists + * (optional specific exception) + * @throws IOException + * if an I/O error occurs or the parent directory does not exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the new file. + */ + public static Path createFile(Path path, FileAttribute>... attrs) + throws IOException + { + EnumSet
options = + EnumSet. of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); + newByteChannel(path, options, attrs).close(); + return path; + } + + /** + * Creates a new directory. The check for the existence of the file and the + * creation of the directory if it does not exist are a single operation + * that is atomic with respect to all other filesystem activities that might + * affect the directory. The {@link #createDirectories createDirectories} + * method should be used where it is required to create all nonexistent + * parent directories first. + * + * The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when creating the directory. Each + * attribute is identified by its {@link FileAttribute#name name}. If more + * than one attribute of the same name is included in the array then all but + * the last occurrence is ignored. + * + * @param dir + * the directory to create + * @param attrs + * an optional list of file attributes to set atomically when + * creating the directory + * + * @return the directory + * + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws FileAlreadyExistsException + * if a directory could not otherwise be created because a file of + * that name already exists (optional specific exception) + * @throws IOException + * if an I/O error occurs or the parent directory does not exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the new directory. + */ + public static Path createDirectory(Path dir, FileAttribute>... attrs) + throws IOException + { + provider(dir).createDirectory(dir, attrs); + return dir; + } + + /** + * Creates a directory by creating all nonexistent parent directories first. + * Unlike the {@link #createDirectory createDirectory} method, an exception + * is not thrown if the directory could not be created because it already + * exists. + * + *
The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when creating the nonexistent + * directories. Each file attribute is identified by its {@link + * FileAttribute#name name}. If more than one attribute of the same name is + * included in the array then all but the last occurrence is ignored. + * + *
If this method fails, then it may do so after creating some, but not + * all, of the parent directories. + * + * @param dir + * the directory to create + * + * @param attrs + * an optional list of file attributes to set atomically when + * creating the directory + * + * @return the directory + * + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws FileAlreadyExistsException + * if {@code dir} exists but is not a directory (optional specific + * exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * in the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked prior to attempting to create a directory and + * its {@link SecurityManager#checkRead(String) checkRead} is + * invoked for each parent directory that is checked. If {@code + * dir} is not an absolute path then its {@link Path#toAbsolutePath + * toAbsolutePath} may need to be invoked to get its absolute path. + * This may invoke the security manager's {@link + * SecurityManager#checkPropertyAccess(String) checkPropertyAccess} + * method to check access to the system property {@code user.dir} + */ + public static Path createDirectories(Path dir, FileAttribute>... attrs) + throws IOException + { + // attempt to create the directory + try { + createAndCheckIsDirectory(dir, attrs); + return dir; + } catch (FileAlreadyExistsException x) { + // file exists and is not a directory + throw x; + } catch (IOException x) { + // parent may not exist or other reason + } + SecurityException se = null; + try { + dir = dir.toAbsolutePath(); + } catch (SecurityException x) { + // don't have permission to get absolute path + se = x; + } + // find a decendent that exists + Path parent = dir.getParent(); + while (parent != null) { + try { + provider(parent).checkAccess(parent); + break; + } catch (NoSuchFileException x) { + // does not exist + } + parent = parent.getParent(); + } + if (parent == null) { + // unable to find existing parent + if (se != null) + throw se; + throw new IOException("Root directory does not exist"); + } + + // create directories + Path child = parent; + for (Path name: parent.relativize(dir)) { + child = child.resolve(name); + createAndCheckIsDirectory(child, attrs); + } + return dir; + } + + /** + * Used by createDirectories to attempt to create a directory. A no-op + * if the directory already exists. + */ + private static void createAndCheckIsDirectory(Path dir, + FileAttribute>... attrs) + throws IOException + { + try { + createDirectory(dir, attrs); + } catch (FileAlreadyExistsException x) { + if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS)) + throw x; + } + } + + /** + * Creates a new empty file in the specified directory, using the given + * prefix and suffix strings to generate its name. The resulting + * {@code Path} is associated with the same {@code FileSystem} as the given + * directory. + * + *
The details as to how the name of the file is constructed is + * implementation dependent and therefore not specified. Where possible + * the {@code prefix} and {@code suffix} are used to construct candidate + * names in the same manner as the {@link + * java.io.File#createTempFile(String,String,File)} method. + * + *
As with the {@code File.createTempFile} methods, this method is only + * part of a temporary-file facility. Where used as a work files, + * the resulting file may be opened using the {@link + * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the + * file is deleted when the appropriate {@code close} method is invoked. + * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the + * {@link java.io.File#deleteOnExit} mechanism may be used to delete the + * file automatically. + * + *
The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when creating the file. Each attribute + * is identified by its {@link FileAttribute#name name}. If more than one + * attribute of the same name is included in the array then all but the last + * occurrence is ignored. When no file attributes are specified, then the + * resulting file may have more restrictive access permissions to files + * created by the {@link java.io.File#createTempFile(String,String,File)} + * method. + * + * @param dir + * the path to directory in which to create the file + * @param prefix + * the prefix string to be used in generating the file's name; + * may be {@code null} + * @param suffix + * the suffix string to be used in generating the file's name; + * may be {@code null}, in which case "{@code .tmp}" is used + * @param attrs + * an optional list of file attributes to set atomically when + * creating the file + * + * @return the path to the newly created file that did not exist before + * this method was invoked + * + * @throws IllegalArgumentException + * if the prefix or suffix parameters cannot be used to generate + * a candidate file name + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws IOException + * if an I/O error occurs or {@code dir} does not exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. + */ + public static Path createTempFile(Path dir, + String prefix, + String suffix, + FileAttribute>... attrs) + throws IOException + { + return TempFileHelper.createTempFile(dir, prefix, suffix, attrs); + } + + /** + * Creates an empty file in the default temporary-file directory, using + * the given prefix and suffix to generate its name. The resulting {@code + * Path} is associated with the default {@code FileSystem}. + * + *
This method works in exactly the manner specified by the + * {@link #createTempFile(Path,String,String,FileAttribute[])} method for + * the case that the {@code dir} parameter is the temporary-file directory. + * + * @param prefix + * the prefix string to be used in generating the file's name; + * may be {@code null} + * @param suffix + * the suffix string to be used in generating the file's name; + * may be {@code null}, in which case "{@code .tmp}" is used + * @param attrs + * an optional list of file attributes to set atomically when + * creating the file + * + * @return the path to the newly created file that did not exist before + * this method was invoked + * + * @throws IllegalArgumentException + * if the prefix or suffix parameters cannot be used to generate + * a candidate file name + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws IOException + * if an I/O error occurs or the temporary-file directory does not + * exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. + */ + public static Path createTempFile(String prefix, + String suffix, + FileAttribute>... attrs) + throws IOException + { + return TempFileHelper.createTempFile(null, prefix, suffix, attrs); + } + + /** + * Creates a new directory in the specified directory, using the given + * prefix to generate its name. The resulting {@code Path} is associated + * with the same {@code FileSystem} as the given directory. + * + *
The details as to how the name of the directory is constructed is + * implementation dependent and therefore not specified. Where possible + * the {@code prefix} is used to construct candidate names. + * + *
As with the {@code createTempFile} methods, this method is only + * part of a temporary-file facility. A {@link Runtime#addShutdownHook + * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be + * used to delete the directory automatically. + * + *
The {@code attrs} parameter is optional {@link FileAttribute + * file-attributes} to set atomically when creating the directory. Each + * attribute is identified by its {@link FileAttribute#name name}. If more + * than one attribute of the same name is included in the array then all but + * the last occurrence is ignored. + * + * @param dir + * the path to directory in which to create the directory + * @param prefix + * the prefix string to be used in generating the directory's name; + * may be {@code null} + * @param attrs + * an optional list of file attributes to set atomically when + * creating the directory + * + * @return the path to the newly created directory that did not exist before + * this method was invoked + * + * @throws IllegalArgumentException + * if the prefix cannot be used to generate a candidate directory name + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws IOException + * if an I/O error occurs or {@code dir} does not exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access when creating the + * directory. + */ + public static Path createTempDirectory(Path dir, + String prefix, + FileAttribute>... attrs) + throws IOException + { + return TempFileHelper.createTempDirectory(dir, prefix, attrs); + } + + /** + * Creates a new directory in the default temporary-file directory, using + * the given prefix and suffix to generate its name. The resulting {@code + * Path} is associated with the default {@code FileSystem}. + * + *
This method works in exactly the manner specified by {@link + * #createTempDirectory(Path,String,FileAttribute[])} method for the case + * that the {@code dir} parameter is the temporary-file directory. + * + * @param prefix + * the prefix string to be used in generating the directory's name; + * may be {@code null} + * @param attrs + * an optional list of file attributes to set atomically when + * creating the directory + * + * @return the path to the newly created directory that did not exist before + * this method was invoked + * + * @throws IllegalArgumentException + * if the prefix cannot be used to generate a candidate directory name + * @throws UnsupportedOperationException + * if the array contains an attribute that cannot be set atomically + * when creating the directory + * @throws IOException + * if an I/O error occurs or the temporary-file directory does not + * exist + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access when creating the + * directory. + */ + public static Path createTempDirectory(String prefix, + FileAttribute>... attrs) + throws IOException + { + return TempFileHelper.createTempDirectory(null, prefix, attrs); + } + + /** + * Creates a symbolic link to a target (optional operation). + * + *
The {@code target} parameter is the target of the link. It may be an + * {@link Path#isAbsolute absolute} or relative path and may not exist. When + * the target is a relative path then file system operations on the resulting + * link are relative to the path of the link. + * + *
The {@code attrs} parameter is optional {@link FileAttribute + * attributes} to set atomically when creating the link. Each attribute is + * identified by its {@link FileAttribute#name name}. If more than one attribute + * of the same name is included in the array then all but the last occurrence + * is ignored. + * + *
Where symbolic links are supported, but the underlying {@link FileStore} + * does not support symbolic links, then this may fail with an {@link + * IOException}. Additionally, some operating systems may require that the + * Java virtual machine be started with implementation specific privileges to + * create symbolic links, in which case this method may throw {@code IOException}. + * + * @param link + * the path of the symbolic link to create + * @param target + * the target of the symbolic link + * @param attrs + * the array of attributes to set atomically when creating the + * symbolic link + * + * @return the path to the symbolic link + * + * @throws UnsupportedOperationException + * if the implementation does not support symbolic links or the + * array contains an attribute that cannot be set atomically when + * creating the symbolic link + * @throws FileAlreadyExistsException + * if a file with the name already exists (optional specific + * exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager + * is installed, it denies {@link LinkPermission}("symbolic") + * or its {@link SecurityManager#checkWrite(String) checkWrite} + * method denies write access to the path of the symbolic link. + */ + public static Path createSymbolicLink(Path link, Path target, + FileAttribute>... attrs) + throws IOException + { + provider(link).createSymbolicLink(link, target, attrs); + return link; + } + + /** + * Creates a new link (directory entry) for an existing file (optional + * operation). + * + *
The {@code link} parameter locates the directory entry to create. + * The {@code existing} parameter is the path to an existing file. This + * method creates a new directory entry for the file so that it can be + * accessed using {@code link} as the path. On some file systems this is + * known as creating a "hard link". Whether the file attributes are + * maintained for the file or for each directory entry is file system + * specific and therefore not specified. Typically, a file system requires + * that all links (directory entries) for a file be on the same file system. + * Furthermore, on some platforms, the Java virtual machine may require to + * be started with implementation specific privileges to create hard links + * or to create links to directories. + * + * @param link + * the link (directory entry) to create + * @param existing + * a path to an existing file + * + * @return the path to the link (directory entry) + * + * @throws UnsupportedOperationException + * if the implementation does not support adding an existing file + * to a directory + * @throws FileAlreadyExistsException + * if the entry could not otherwise be created because a file of + * that name already exists (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager + * is installed, it denies {@link LinkPermission}("hard") + * or its {@link SecurityManager#checkWrite(String) checkWrite} + * method denies write access to either the link or the + * existing file. + */ + public static Path createLink(Path link, Path existing) throws IOException { + provider(link).createLink(link, existing); + return link; + } + + /** + * Deletes a file. + * + *
An implementation may require to examine the file to determine if the + * file is a directory. Consequently this method may not be atomic with respect + * to other file system operations. If the file is a symbolic link then the + * symbolic link itself, not the final target of the link, is deleted. + * + *
If the file is a directory then the directory must be empty. In some + * implementations a directory has entries for special files or links that + * are created when the directory is created. In such implementations a + * directory is considered empty when only the special entries exist. + * This method can be used with the {@link #walkFileTree walkFileTree} + * method to delete a directory and all entries in the directory, or an + * entire file-tree where required. + * + *
On some operating systems it may not be possible to remove a file when + * it is open and in use by this Java virtual machine or other programs. + * + * @param path + * the path to the file to delete + * + * @throws NoSuchFileException + * if the file does not exist (optional specific exception) + * @throws DirectoryNotEmptyException + * if the file is a directory and could not otherwise be deleted + * because the directory is not empty (optional specific + * exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkDelete(String)} method + * is invoked to check delete access to the file + */ + public static void delete(Path path) throws IOException { + provider(path).delete(path); + } + + /** + * Deletes a file if it exists. + * + *
As with the {@link #delete(Path) delete(Path)} method, an + * implementation may need to examine the file to determine if the file is a + * directory. Consequently this method may not be atomic with respect to + * other file system operations. If the file is a symbolic link, then the + * symbolic link itself, not the final target of the link, is deleted. + * + *
If the file is a directory then the directory must be empty. In some + * implementations a directory has entries for special files or links that + * are created when the directory is created. In such implementations a + * directory is considered empty when only the special entries exist. + * + *
On some operating systems it may not be possible to remove a file when + * it is open and in use by this Java virtual machine or other programs. + * + * @param path + * the path to the file to delete + * + * @return {@code true} if the file was deleted by this method; {@code + * false} if the file could not be deleted because it did not + * exist + * + * @throws DirectoryNotEmptyException + * if the file is a directory and could not otherwise be deleted + * because the directory is not empty (optional specific + * exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkDelete(String)} method + * is invoked to check delete access to the file. + */ + public static boolean deleteIfExists(Path path) throws IOException { + return provider(path).deleteIfExists(path); + } + + // -- Copying and moving files -- + + /** + * Copy a file to a target file. + * + *
This method copies a file to the target file with the {@code + * options} parameter specifying how the copy is performed. By default, the + * copy fails if the target file already exists or is a symbolic link, + * except if the source and target are the {@link #isSameFile same} file, in + * which case the method completes without copying the file. File attributes + * are not required to be copied to the target file. If symbolic links are + * supported, and the file is a symbolic link, then the final target of the + * link is copied. If the file is a directory then it creates an empty + * directory in the target location (entries in the directory are not + * copied). This method can be used with the {@link #walkFileTree + * walkFileTree} method to copy a directory and all entries in the directory, + * or an entire file-tree where required. + * + *
The {@code options} parameter may include any of the following: + * + *
+ *
+ * + *+ * Option Description + * + *{@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} + *If the target file exists, then the target file is replaced if it + * is not a non-empty directory. If the target file exists and is a + * symbolic link, then the symbolic link itself, not the target of + * the link, is replaced. + *+ * + *{@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} + *Attempts to copy the file attributes associated with this file to + * the target file. The exact file attributes that are copied is platform + * and file system dependent and therefore unspecified. Minimally, the + * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is + * copied to the target file if supported by both the source and target + * file store. Copying of file timestamps may result in precision + * loss. + *+ * + *{@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} + *Symbolic links are not followed. If the file is a symbolic link, + * then the symbolic link itself, not the target of the link, is copied. + * It is implementation specific if file attributes can be copied to the + * new link. In other words, the {@code COPY_ATTRIBUTES} option may be + * ignored when copying a symbolic link. + *An implementation of this interface may support additional + * implementation specific options. + * + *
Copying a file is not an atomic operation. If an {@link IOException} + * is thrown then it possible that the target file is incomplete or some of + * its file attributes have not been copied from the source file. When the + * {@code REPLACE_EXISTING} option is specified and the target file exists, + * then the target file is replaced. The check for the existence of the file + * and the creation of the new file may not be atomic with respect to other + * file system activities. + * + *
Usage Example: + * Suppose we want to copy a file into a directory, giving it the same file + * name as the source file: + *
+ * Path source = ... + * Path newdir = ... + * Files.copy(source, newdir.resolve(source.getFileName()); + *+ * + * @param source + * the path to the file to copy + * @param target + * the path to the target file (may be associated with a different + * provider to the source path) + * @param options + * options specifying how the copy should be done + * + * @return the path to the target file + * + * @throws UnsupportedOperationException + * if the array contains a copy option that is not supported + * @throws FileAlreadyExistsException + * if the target file exists but cannot be replaced because the + * {@code REPLACE_EXISTING} option is not specified (optional + * specific exception) + * @throws DirectoryNotEmptyException + * the {@code REPLACE_EXISTING} option is specified but the file + * cannot be replaced because it is a non-empty directory + * (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the source file, the + * {@link SecurityManager#checkWrite(String) checkWrite} is invoked + * to check write access to the target file. If a symbolic link is + * copied the security manager is invoked to check {@link + * LinkPermission}{@code ("symbolic")}. + */ + public static Path copy(Path source, Path target, CopyOption... options) + throws IOException + { + FileSystemProvider provider = provider(source); + if (provider(target) == provider) { + // same provider + provider.copy(source, target, options); + } else { + // different providers + CopyMoveHelper.copyToForeignTarget(source, target, options); + } + return target; + } + + /** + * Move or rename a file to a target file. + * + *By default, this method attempts to move the file to the target + * file, failing if the target file exists except if the source and + * target are the {@link #isSameFile same} file, in which case this method + * has no effect. If the file is a symbolic link then the symbolic link + * itself, not the target of the link, is moved. This method may be + * invoked to move an empty directory. In some implementations a directory + * has entries for special files or links that are created when the + * directory is created. In such implementations a directory is considered + * empty when only the special entries exist. When invoked to move a + * directory that is not empty then the directory is moved if it does not + * require moving the entries in the directory. For example, renaming a + * directory on the same {@link FileStore} will usually not require moving + * the entries in the directory. When moving a directory requires that its + * entries be moved then this method fails (by throwing an {@code + * IOException}). To move a file tree may involve copying rather + * than moving directories and this can be done using the {@link + * #copy copy} method in conjunction with the {@link + * #walkFileTree Files.walkFileTree} utility method. + * + *
The {@code options} parameter may include any of the following: + * + *
+ *
+ * + *+ * Option Description + * + *{@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} + *If the target file exists, then the target file is replaced if it + * is not a non-empty directory. If the target file exists and is a + * symbolic link, then the symbolic link itself, not the target of + * the link, is replaced. + *+ * {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} + *The move is performed as an atomic file system operation and all + * other options are ignored. If the target file exists then it is + * implementation specific if the existing file is replaced or this method + * fails by throwing an {@link IOException}. If the move cannot be + * performed as an atomic file system operation then {@link + * AtomicMoveNotSupportedException} is thrown. This can arise, for + * example, when the target location is on a different {@code FileStore} + * and would require that the file be copied, or target location is + * associated with a different provider to this object. + *An implementation of this interface may support additional + * implementation specific options. + * + *
Where the move requires that the file be copied then the {@link + * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the + * new file. An implementation may also attempt to copy other file + * attributes but is not required to fail if the file attributes cannot be + * copied. When the move is performed as a non-atomic operation, and a {@code + * IOException} is thrown, then the state of the files is not defined. The + * original file and the target file may both exist, the target file may be + * incomplete or some of its file attributes may not been copied from the + * original file. + * + *
Usage Examples: + * Suppose we want to rename a file to "newname", keeping the file in the + * same directory: + *
+ * Path source = ... + * Files.move(source, source.resolveSibling("newname")); + *+ * Alternatively, suppose we want to move a file to new directory, keeping + * the same file name, and replacing any existing file of that name in the + * directory: + *+ * Path source = ... + * Path newdir = ... + * Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING); + *+ * + * @param source + * the path to the file to move + * @param target + * the path to the target file (may be associated with a different + * provider to the source path) + * @param options + * options specifying how the move should be done + * + * @return the path to the target file + * + * @throws UnsupportedOperationException + * if the array contains a copy option that is not supported + * @throws FileAlreadyExistsException + * if the target file exists but cannot be replaced because the + * {@code REPLACE_EXISTING} option is not specified (optional + * specific exception) + * @throws DirectoryNotEmptyException + * the {@code REPLACE_EXISTING} option is specified but the file + * cannot be replaced because it is a non-empty directory + * (optional specific exception) + * @throws AtomicMoveNotSupportedException + * if the options array contains the {@code ATOMIC_MOVE} option but + * the file cannot be moved as an atomic file system operation. + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to both the source and + * target file. + */ + public static Path move(Path source, Path target, CopyOption... options) + throws IOException + { + FileSystemProvider provider = provider(source); + if (provider(target) == provider) { + // same provider + provider.move(source, target, options); + } else { + // different providers + CopyMoveHelper.moveToForeignTarget(source, target, options); + } + return target; + } + + // -- Miscellenous -- + + /** + * Reads the target of a symbolic link (optional operation). + * + *If the file system supports symbolic + * links then this method is used to read the target of the link, failing + * if the file is not a symbolic link. The target of the link need not exist. + * The returned {@code Path} object will be associated with the same file + * system as {@code link}. + * + * @param link + * the path to the symbolic link + * + * @return a {@code Path} object representing the target of the link + * + * @throws UnsupportedOperationException + * if the implementation does not support symbolic links + * @throws NotLinkException + * if the target could otherwise not be read because the file + * is not a symbolic link (optional specific exception) + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager + * is installed, it checks that {@code FilePermission} has been + * granted with the "{@code readlink}" action to read the link. + */ + public static Path readSymbolicLink(Path link) throws IOException { + return provider(link).readSymbolicLink(link); + } + + /** + * Returns the {@link FileStore} representing the file store where a file + * is located. + * + *
Once a reference to the {@code FileStore} is obtained it is + * implementation specific if operations on the returned {@code FileStore}, + * or {@link FileStoreAttributeView} objects obtained from it, continue + * to depend on the existence of the file. In particular the behavior is not + * defined for the case that the file is deleted or moved to a different + * file store. + * + * @param path + * the path to the file + * + * @return the file store where the file is stored + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file, and in + * addition it checks {@link RuntimePermission} + * ("getFileStoreAttributes") + */ + public static FileStore getFileStore(Path path) throws IOException { + return provider(path).getFileStore(path); + } + + /** + * Tests if two paths locate the same file. + * + *
If both {@code Path} objects are {@link Path#equals(Object) equal} + * then this method returns {@code true} without checking if the file exists. + * If the two {@code Path} objects are associated with different providers + * then this method returns {@code false}. Otherwise, this method checks if + * both {@code Path} objects locate the same file, and depending on the + * implementation, may require to open or access both files. + * + *
If the file system and files remain static, then this method implements + * an equivalence relation for non-null {@code Paths}. + *
+ *
+ * + * @param path + * one path to the file + * @param path2 + * the other path + * + * @return {@code true} if, and only if, the two paths locate the same file + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to both files. + * + * @see java.nio.file.attribute.BasicFileAttributes#fileKey + */ + public static boolean isSameFile(Path path, Path path2) throws IOException { + return provider(path).isSameFile(path, path2); + } + + /** + * Tells whether or not a file is considered hidden. The exact + * definition of hidden is platform or provider dependent. On UNIX for + * example a file is considered to be hidden if its name begins with a + * period character ('.'). On Windows a file is considered hidden if it + * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden} + * attribute is set. + * + *- It is reflexive: for {@code Path} {@code f}, + * {@code isSameFile(f,f)} should return {@code true}. + *
- It is symmetric: for two {@code Paths} {@code f} and {@code g}, + * {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}. + *
- It is transitive: for three {@code Paths} + * {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns + * {@code true} and {@code isSameFile(g,h)} returns {@code true}, then + * {@code isSameFile(g,h)} will return return {@code true}. + *
Depending on the implementation this method may require to access + * the file system to determine if the file is considered hidden. + * + * @param path + * the path to the file to test + * + * @return {@code true} if the file is considered hidden + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + */ + public static boolean isHidden(Path path) throws IOException { + return provider(path).isHidden(path); + } + + // lazy loading of default and installed file type detectors + private static class FileTypeDetectors{ + static final FileTypeDetector defaultFileTypeDetector = + sun.nio.fs.DefaultFileTypeDetector.create(); + static final List
installeDetectors = + loadInstalledDetectors(); + + // loads all installed file type detectors + private static List loadInstalledDetectors() { + return AccessController + .doPrivileged(new PrivilegedAction >() { + @Override public List
run() { + List list = new ArrayList<>(); + ServiceLoader loader = ServiceLoader + .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader()); + for (FileTypeDetector detector: loader) { + list.add(detector); + } + return list; + }}); + } + } + + /** + * Probes the content type of a file. + * + * This method uses the installed {@link FileTypeDetector} implementations + * to probe the given file to determine its content type. Each file type + * detector's {@link FileTypeDetector#probeContentType probeContentType} is + * invoked, in turn, to probe the file type. If the file is recognized then + * the content type is returned. If the file is not recognized by any of the + * installed file type detectors then a system-default file type detector is + * invoked to guess the content type. + * + *
A given invocation of the Java virtual machine maintains a system-wide + * list of file type detectors. Installed file type detectors are loaded + * using the service-provider loading facility defined by the {@link ServiceLoader} + * class. Installed file type detectors are loaded using the system class + * loader. If the system class loader cannot be found then the extension class + * loader is used; If the extension class loader cannot be found then the + * bootstrap class loader is used. File type detectors are typically installed + * by placing them in a JAR file on the application class path or in the + * extension directory, the JAR file contains a provider-configuration file + * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory + * {@code META-INF/services}, and the file lists one or more fully-qualified + * names of concrete subclass of {@code FileTypeDetector } that have a zero + * argument constructor. If the process of locating or instantiating the + * installed file type detectors fails then an unspecified error is thrown. + * The ordering that installed providers are located is implementation + * specific. + * + *
The return value of this method is the string form of the value of a + * Multipurpose Internet Mail Extension (MIME) content type as + * defined by RFC 2045: + * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet + * Message Bodies. The string is guaranteed to be parsable according + * to the grammar in the RFC. + * + * @param path + * the path to the file to probe + * + * @return The content type of the file, or {@code null} if the content + * type cannot be determined + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * If a security manager is installed and it denies an unspecified + * permission required by a file type detector implementation. + */ + public static String probeContentType(Path path) + throws IOException + { + // try installed file type detectors + for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) { + String result = detector.probeContentType(path); + if (result != null) + return result; + } + + // fallback to default + return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path); + } + + // -- File Attributes -- + + /** + * Returns a file attribute view of a given type. + * + *
A file attribute view provides a read-only or updatable view of a + * set of file attributes. This method is intended to be used where the file + * attribute view defines type-safe methods to read or update the file + * attributes. The {@code type} parameter is the type of the attribute view + * required and the method returns an instance of that type if supported. + * The {@link BasicFileAttributeView} type supports access to the basic + * attributes of a file. Invoking this method to select a file attribute + * view of that type will always return an instance of that class. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled by the resulting file attribute view for the case that the + * file is a symbolic link. By default, symbolic links are followed. If the + * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then + * symbolic links are not followed. This option is ignored by implementations + * that do not support symbolic links. + * + *
Usage Example: + * Suppose we want read or set a file's ACL, if supported: + *
+ * Path path = ... + * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); + * if (view != null) { + * List<AclEntry> acl = view.getAcl(); + * : + * } + *+ * + * + * @param path + * the path to the file + * @param type + * the {@code Class} object corresponding to the file attribute view + * @param options + * options indicating how symbolic links are handled + * + * @return a file attribute view of the specified type, or {@code null} if + * the attribute view type is not available + */ + public staticV getFileAttributeView(Path path, + Class type, + LinkOption... options) + { + return provider(path).getFileAttributeView(path, type, options); + } + + /** + * Reads a file's attributes as a bulk operation. + * + * The {@code type} parameter is the type of the attributes required + * and this method returns an instance of that type if supported. All + * implementations support a basic set of file attributes and so invoking + * this method with a {@code type} parameter of {@code + * BasicFileAttributes.class} will not throw {@code + * UnsupportedOperationException}. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
It is implementation specific if all file attributes are read as an + * atomic operation with respect to other file system operations. + * + *
Usage Example: + * Suppose we want to read a file's attributes in bulk: + *
+ * Path path = ... + * BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); + *+ * Alternatively, suppose we want to read file's POSIX attributes without + * following symbolic links: + *+ * PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS); + *+ * + * @param path + * the path to the file + * @param type + * the {@code Class} of the file attributes required + * to read + * @param options + * options indicating how symbolic links are handled + * + * @return the file attributes + * + * @throws UnsupportedOperationException + * if an attributes of the given type are not supported + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. If this + * method is invoked to read security sensitive attributes then the + * security manager may be invoke to check for additional permissions. + */ + public static A readAttributes(Path path, + Class type, + LinkOption... options) + throws IOException + { + return provider(path).readAttributes(path, type, options); + } + + /** + * Sets the value of a file attribute. + * + *The {@code attribute} parameter identifies the attribute to be set + * and takes the form: + *
+ * [view-name:]attribute-name + *+ * where square brackets [...] delineate an optional component and the + * character {@code ':'} stands for itself. + * + *view-name is the {@link FileAttributeView#name name} of a {@link + * FileAttributeView} that identifies a set of file attributes. If not + * specified then it defaults to {@code "basic"}, the name of the file + * attribute view that identifies the basic set of file attributes common to + * many file systems. attribute-name is the name of the attribute + * within the set. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Usage Example: + * Suppose we want to set the DOS "hidden" attribute: + *
+ * Path path = ... + * Files.setAttribute(path, "dos:hidden", true); + *+ * + * @param path + * the path to the file + * @param attribute + * the attribute to set + * @param value + * the attribute value + * @param options + * options indicating how symbolic links are handled + * + * @return the {@code path} parameter + * + * @throws UnsupportedOperationException + * if the attribute view is not available or it does not support + * updating the attribute + * @throws IllegalArgumentException + * if the attribute value is of the correct type but has an + * inappropriate value + * @throws ClassCastException + * if the attribute value is not of the expected type or is a + * collection containing elements that are not of the expected + * type + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkWrite(String) checkWrite} + * method denies write access to the file. If this method is invoked + * to set security sensitive attributes then the security manager + * may be invoked to check for additional permissions. + */ + public static Path setAttribute(Path path, String attribute, Object value, + LinkOption... options) + throws IOException + { + provider(path).setAttribute(path, attribute, value, options); + return path; + } + + /** + * Reads the value of a file attribute. + * + *The {@code attribute} parameter identifies the attribute to be read + * and takes the form: + *
+ * [view-name:]attribute-name + *+ * where square brackets [...] delineate an optional component and the + * character {@code ':'} stands for itself. + * + *view-name is the {@link FileAttributeView#name name} of a {@link + * FileAttributeView} that identifies a set of file attributes. If not + * specified then it defaults to {@code "basic"}, the name of the file + * attribute view that identifies the basic set of file attributes common to + * many file systems. attribute-name is the name of the attribute. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Usage Example: + * Suppose we require the user ID of the file owner on a system that + * supports a "{@code unix}" view: + *
+ * Path path = ... + * int uid = (Integer)Files.getAttribute(path, "unix:uid"); + *+ * + * @param path + * the path to the file + * @param attribute + * the attribute to read + * @param options + * options indicating how symbolic links are handled + * + * @return the attribute value or {@code null} if the attribute view + * is not available or it does not support reading the attribute + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. If this method is invoked + * to read security sensitive attributes then the security manager + * may be invoked to check for additional permissions. + */ + public static Object getAttribute(Path path, String attribute, + LinkOption... options) + throws IOException + { + // only one attribute should be read + if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0) + return null; + Mapmap = readAttributes(path, attribute, options); + String name; + int pos = attribute.indexOf(':'); + if (pos == -1) { + name = attribute; + } else { + name = (pos == attribute.length()) ? "" : attribute.substring(pos+1); + } + return map.get(name); + } + + /** + * Reads a set of file attributes as a bulk operation. + * + * - * - *The {@code attributes} parameter identifies the attributes to be read + * and takes the form: + *
+ * [view-name:]attribute-list + *+ * where square brackets [...] delineate an optional component and the + * character {@code ':'} stands for itself. + * + *view-name is the {@link FileAttributeView#name name} of a {@link + * FileAttributeView} that identifies a set of file attributes. If not + * specified then it defaults to {@code "basic"}, the name of the file + * attribute view that identifies the basic set of file attributes common to + * many file systems. + * + *
The attribute-list component is a comma separated list of + * zero or more names of attributes to read. If the list contains the value + * {@code "*"} then all attributes are read. Attributes that are not supported + * are ignored and will not be present in the returned map. It is + * implementation specific if all attributes are read as an atomic operation + * with respect to other file system operations. + * + *
The following examples demonstrate possible values for the {@code + * attributes} parameter: + * + *
+ *+ * + *+ *
+ *+ * + *{@code "*"} + *Read all {@link BasicFileAttributes basic-file-attributes}. + *+ * + *{@code "size,lastModifiedTime,lastAccessTime"} + *Reads the file size, last modified time, and last access time + * attributes. + *+ * + *{@code "posix:*"} + *Read all {@link PosixFileAttributes POSIX-file-attributes}. + *+ * + *{@code "posix:permissions,owner,size"} + *Reads the POSX file permissions, owner, and file size. + *The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + * @param path + * the path to the file + * @param attributes + * the attributes to read + * @param options + * options indicating how symbolic links are handled + * + * @return a map of the attributes returned; may be empty. The map's keys + * are the attribute names, its values are the attribute values + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. If this method is invoked + * to read security sensitive attributes then the security manager + * may be invoke to check for additional permissions. + */ + public static Map
readAttributes(Path path, String attributes, + LinkOption... options) + throws IOException + { + return provider(path).readAttributes(path, attributes, options); + } + + /** + * Returns a file's POSIX file permissions. + * + * The {@code path} parameter is associated with a {@code FileSystem} + * that supports the {@link PosixFileAttributeView}. This attribute view + * provides access to file attributes commonly associated with files on file + * systems used by operating systems that implement the Portable Operating + * System Interface (POSIX) family of standards. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + * @param path + * the path to the file + * @param options + * options indicating how symbolic links are handled + * + * @return the file permissions + * + * @throws UnsupportedOperationException + * if the associated file system does not support the {@code + * PosixFileAttributeView} + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, a security manager is + * installed, and it denies {@link RuntimePermission}("accessUserInformation") + * or its {@link SecurityManager#checkRead(String) checkRead} method + * denies read access to the file. + */ + public static Set
getPosixFilePermissions(Path path, + LinkOption... options) + throws IOException + { + return readAttributes(path, PosixFileAttributes.class, options).permissions(); + } + + /** + * Sets a file's POSIX permissions. + * + * The {@code path} parameter is associated with a {@code FileSystem} + * that supports the {@link PosixFileAttributeView}. This attribute view + * provides access to file attributes commonly associated with files on file + * systems used by operating systems that implement the Portable Operating + * System Interface (POSIX) family of standards. + * + * @param path + * A file reference that locates the file + * @param perms + * The new set of permissions + * + * @throws UnsupportedOperationException + * if the associated file system does not support the {@code + * PosixFileAttributeView} + * @throws ClassCastException + * if the sets contains elements that are not of type {@code + * PosixFilePermission} + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, it denies {@link RuntimePermission}("accessUserInformation") + * or its {@link SecurityManager#checkWrite(String) checkWrite} + * method denies write access to the file. + */ + public static Path setPosixFilePermissions(Path path, + Set
perms) + throws IOException + { + PosixFileAttributeView view = + getFileAttributeView(path, PosixFileAttributeView.class); + if (view == null) + throw new UnsupportedOperationException(); + view.setPermissions(perms); + return path; + } + + /** + * Returns the owner of a file. + * + * The {@code path} parameter is associated with a file system that + * supports {@link FileOwnerAttributeView}. This file attribute view provides + * access to a file attribute that is the owner of the file. + * + * @param path + * A file reference that locates the file + * @param options + * options indicating how symbolic links are handled + * + * @return A user principal representing the owner of the file + * + * @throws UnsupportedOperationException + * if the associated file system does not support the {@code + * FileOwnerAttributeView} + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, it denies {@link RuntimePermission}("accessUserInformation") + * or its {@link SecurityManager#checkRead(String) checkRead} method + * denies read access to the file. + */ + public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException { + FileOwnerAttributeView view = + getFileAttributeView(path, FileOwnerAttributeView.class, options); + if (view == null) + throw new UnsupportedOperationException(); + return view.getOwner(); + } + + /** + * Updates the file owner. + * + *
The {@code path} parameter is associated with a file system that + * supports {@link FileOwnerAttributeView}. This file attribute view provides + * access to a file attribute that is the owner of the file. + * + *
Usage Example: + * Suppose we want to make "joe" the owner of a file: + *
+ * Path path = ... + * UserPrincipalLookupService lookupService = + * provider(path).getUserPrincipalLookupService(); + * UserPrincipal joe = lookupService.lookupPrincipalByName("joe"); + * Files.setOwner(path, joe); + *+ * + * @param path + * A file reference that locates the file + * @param owner + * The new file owner + * + * @throws UnsupportedOperationException + * if the associated file system does not support the {@code + * FileOwnerAttributeView} + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, it denies {@link RuntimePermission}("accessUserInformation") + * or its {@link SecurityManager#checkWrite(String) checkWrite} + * method denies write access to the file. + * + * @see FileSystem#getUserPrincipalLookupService + * @see java.nio.file.attribute.UserPrincipalLookupService + */ + public static Path setOwner(Path path, UserPrincipal owner) + throws IOException + { + FileOwnerAttributeView view = + getFileAttributeView(path, FileOwnerAttributeView.class); + if (view == null) + throw new UnsupportedOperationException(); + view.setOwner(owner); + return path; + } + + /** + * Tests whether a file is a symbolic link. + * + *Where is it required to distinguish an I/O exception from the case + * that the file is not a symbolic link then the file attributes can be + * read with the {@link #readAttributes(Path,Class,LinkOption[]) + * readAttributes} method and the file type tested with the {@link + * BasicFileAttributes#isSymbolicLink} method. + * + * @return {@code true} if the file is a symbolic link; {@code false} if + * the file does not exist, is not a symbolic link, or it cannot + * be determined if the file is symbolic link or not. + * + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. + */ + public static boolean isSymbolicLink(Path path) { + try { + return readAttributes(path, + BasicFileAttributes.class, + LinkOption.NOFOLLOW_LINKS).isSymbolicLink(); + } catch (IOException ioe) { + return false; + } + } + + /** + * Tests whether a file is a directory. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Where is it required to distinguish an I/O exception from the case + * that the file is not a directory then the file attributes can be + * read with the {@link #readAttributes(Path,Class,LinkOption[]) + * readAttributes} method and the file type tested with the {@link + * BasicFileAttributes#isDirectory} method. + * + * @param path + * the path to the file to test + * @param options + * options indicating how symbolic links are handled + * + * @return {@code true} if the file is a directory; {@code false} if + * the file does not exist, is not a directory, or it cannot + * be determined if the file is directory or not. + * + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. + */ + public static boolean isDirectory(Path path, LinkOption... options) { + try { + return readAttributes(path, BasicFileAttributes.class, options).isDirectory(); + } catch (IOException ioe) { + return false; + } + } + + /** + * Tests whether a file is a regular file with opaque content. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Where is it required to distinguish an I/O exception from the case + * that the file is not a regular file then the file attributes can be + * read with the {@link #readAttributes(Path,Class,LinkOption[]) + * readAttributes} method and the file type tested with the {@link + * BasicFileAttributes#isRegularFile} method. + * + * @param path + * the path to the file + * @param options + * options indicating how symbolic links are handled + * + * @return {@code true} if the file is a regular file; {@code false} if + * the file does not exist, is not a direcregular filetory, or it + * cannot be determined if the file is regular file or not. + * + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. + */ + public static boolean isRegularFile(Path path, LinkOption... options) { + try { + return readAttributes(path, BasicFileAttributes.class, options).isRegularFile(); + } catch (IOException ioe) { + return false; + } + } + + /** + * Returns a file's last modified time. + * + *
The {@code options} array may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed and the file attribute of the final target + * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + * @param path + * the path to the file + * @param options + * options indicating how symbolic links are handled + * + * @return a {@code FileTime} representing the time the file was last + * modified, or an implementation specific default when a time + * stamp to indicate the time of last modification is not supported + * by the file system + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. + * + * @see BasicFileAttributes#lastModifiedTime + */ + public static FileTime getLastModifiedTime(Path path, LinkOption... options) + throws IOException + { + return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime(); + } + + /** + * Updates a file's last modified time attribute. The file time is converted + * to the epoch and precision supported by the file system. Converting from + * finer to coarser granularities result in precision loss. The behavior of + * this method when attempting to set the last modified time when it is not + * supported by the file system or is outside the range supported by the + * underlying file store is not defined. It may or not fail by throwing an + * {@code IOException}. + * + *
Usage Example: + * Suppose we want to set the last modified time to the current time: + *
+ * Path path = ... + * FileTime now = FileTime.fromMillis(System.currentTimeMillis()); + * Files.setLastModifiedTime(path, now); + *+ * + * @param path + * the path to the file + * @param time + * the new last modified time + * + * @return the file + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, the security manager's {@link + * SecurityManager#checkWrite(String) checkWrite} method is invoked + * to check write access to file + * + * @see BasicFileAttributeView#setTimes + */ + public static Path setLastModifiedTime(Path path, FileTime time) + throws IOException + { + getFileAttributeView(path, BasicFileAttributeView.class) + .setTimes(time, null, null); + return path; + } + + /** + * Returns the size of a file (in bytes). The size may differ from the + * actual size on the file system due to compression, support for sparse + * files, or other reasons. The size of files that are not {@link + * #isRegularFile regular} files is implementation specific and + * therefore unspecified. + * + * @param path + * the path to the file + * + * @return the file size, in bytes + * + * @throws IOException + * if an I/O error occurs + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, its {@link SecurityManager#checkRead(String) checkRead} + * method denies read access to the file. + * + * @see BasicFileAttributes#size + */ + public static long size(Path path) throws IOException { + return readAttributes(path, BasicFileAttributes.class).size(); + } + + // -- Accessibility -- + + /** + * Returns {@code false} if NOFOLLOW_LINKS is present. + */ + private static boolean followLinks(LinkOption... options) { + boolean followLinks = true; + for (LinkOption opt: options) { + if (opt == LinkOption.NOFOLLOW_LINKS) { + followLinks = false; + continue; + } + if (opt == null) + throw new NullPointerException(); + throw new AssertionError("Should not get here"); + } + return followLinks; + } + + /** + * Tests whether a file exists. + * + *The {@code options} parameter may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Note that the result of this method is immediately outdated. If this + * method indicates the file exists then there is no guarantee that a + * subsequence access will succeed. Care should be taken when using this + * method in security sensitive applications. + * + * @param path + * the path to the file to test + * @param options + * options indicating how symbolic links are handled + * . + * @return {@code true} if the file exists; {@code false} if the file does + * not exist or its existence cannot be determined. + * + * @throws SecurityException + * In the case of the default provider, the {@link + * SecurityManager#checkRead(String)} is invoked to check + * read access to the file. + * + * @see #notExists + */ + public static boolean exists(Path path, LinkOption... options) { + try { + if (followLinks(options)) { + provider(path).checkAccess(path); + } else { + // attempt to read attributes without following links + readAttributes(path, BasicFileAttributes.class, + LinkOption.NOFOLLOW_LINKS); + } + // file exists + return true; + } catch (IOException x) { + // does not exist or unable to determine if file exists + return false; + } + + } + + /** + * Tests whether the file located by this path does not exist. This method + * is intended for cases where it is required to take action when it can be + * confirmed that a file does not exist. + * + *
The {@code options} parameter may be used to indicate how symbolic links + * are handled for the case that the file is a symbolic link. By default, + * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS + * NOFOLLOW_LINKS} is present then symbolic links are not followed. + * + *
Note that this method is not the complement of the {@link #exists + * exists} method. Where it is not possible to determine if a file exists + * or not then both methods return {@code false}. As with the {@code exists} + * method, the result of this method is immediately outdated. If this + * method indicates the file does exist then there is no guarantee that a + * subsequence attempt to create the file will succeed. Care should be taken + * when using this method in security sensitive applications. + * + * @param path + * the path to the file to test + * @param options + * options indicating how symbolic links are handled + * + * @return {@code true} if the file does not exist; {@code false} if the + * file exists or its existence cannot be determined + * + * @throws SecurityException + * In the case of the default provider, the {@link + * SecurityManager#checkRead(String)} is invoked to check + * read access to the file. + */ + public static boolean notExists(Path path, LinkOption... options) { + try { + if (followLinks(options)) { + provider(path).checkAccess(path); + } else { + // attempt to read attributes without following links + readAttributes(path, BasicFileAttributes.class, + LinkOption.NOFOLLOW_LINKS); + } + // file exists + return false; + } catch (NoSuchFileException x) { + // file confirmed not to exist + return true; + } catch (IOException x) { + return false; } } /** - * Probes the content type of a file. + * Used by isReadbale, isWritable, isExecutable to test access to a file. + */ + private static boolean isAccessible(Path path, AccessMode... modes) { + try { + provider(path).checkAccess(path, modes); + return true; + } catch (IOException x) { + return false; + } + } + + /** + * Tests whether a file is readable. This method checks that a file exists + * and that this Java virtual machine has appropriate privileges that would + * allow it open the file for reading. Depending on the implementation, this + * method may require to read file permissions, access control lists, or + * other file attributes in order to check the effective access to the file. + * Consequently, this method may not be atomic with respect to other file + * system operations. * - *
This method uses the installed {@link FileTypeDetector} implementations - * to probe the given file to determine its content type. Each file type - * detector's {@link FileTypeDetector#probeContentType probeContentType} is - * invoked, in turn, to probe the file type. If the file is recognized then - * the content type is returned. If the file is not recognized by any of the - * installed file type detectors then a system-default file type detector is - * invoked to guess the content type. + *
Note that the result of this method is immediately outdated, there is + * no guarantee that a subsequent attempt to open the file for reading will + * succeed (or even that it will access the same file). Care should be taken + * when using this method in security sensitive applications. * - *
A given invocation of the Java virtual machine maintains a system-wide - * list of file type detectors. Installed file type detectors are loaded - * using the service-provider loading facility defined by the {@link ServiceLoader} - * class. Installed file type detectors are loaded using the system class - * loader. If the system class loader cannot be found then the extension class - * loader is used; If the extension class loader cannot be found then the - * bootstrap class loader is used. File type detectors are typically installed - * by placing them in a JAR file on the application class path or in the - * extension directory, the JAR file contains a provider-configuration file - * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory - * {@code META-INF/services}, and the file lists one or more fully-qualified - * names of concrete subclass of {@code FileTypeDetector } that have a zero - * argument constructor. If the process of locating or instantiating the - * installed file type detectors fails then an unspecified error is thrown. - * The ordering that installed providers are located is implementation - * specific. + * @param path + * the path to the file to check * - *
The return value of this method is the string form of the value of a - * Multipurpose Internet Mail Extension (MIME) content type as - * defined by RFC 2045: - * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet - * Message Bodies. The string is guaranteed to be parsable according - * to the grammar in the RFC. + * @return {@code true} if the file exists and is readable; {@code false} + * if the file does not exist, read access would be denied because + * the Java virtual machine has insufficient privileges, or access + * cannot be determined + * + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * is invoked to check read access to the file. + */ + public static boolean isReadable(Path path) { + return isAccessible(path, AccessMode.READ); + } + + /** + * Tests whether a file is writable. This method checks that a file exists + * and that this Java virtual machine has appropriate privileges that would + * allow it open the file for writing. Depending on the implementation, this + * method may require to read file permissions, access control lists, or + * other file attributes in order to check the effective access to the file. + * Consequently, this method may not be atomic with respect to other file + * system operations. * - * @param file - * The file reference + *
Note that result of this method is immediately outdated, there is no + * guarantee that a subsequent attempt to open the file for writing will + * succeed (or even that it will access the same file). Care should be taken + * when using this method in security sensitive applications. * - * @return The content type of the file, or {@code null} if the content - * type cannot be determined + * @param path + * the path to the file to check + * + * @return {@code true} if the file exists and is writable; {@code false} + * if the file does not exist, write access would be denied because + * the Java virtual machine has insufficient privileges, or access + * cannot be determined * - * @throws IOException - * If an I/O error occurs * @throws SecurityException - * If a security manager is installed and it denies an unspecified - * permission required by a file type detector implementation. + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * is invoked to check write access to the file. */ - public static String probeContentType(FileRef file) - throws IOException - { - // try installed file type detectors - for (FileTypeDetector detector: DefaultFileTypeDetectorHolder.installeDetectors) { - String result = detector.probeContentType(file); - if (result != null) - return result; - } + public static boolean isWritable(Path path) { + return isAccessible(path, AccessMode.WRITE); + } - // fallback to default - return DefaultFileTypeDetectorHolder.defaultFileTypeDetector - .probeContentType(file); + /** + * Tests whether a file is executable. This method checks that a file exists + * and that this Java virtual machine has appropriate privileges to {@link + * Runtime#exec execute} the file. The semantics may differ when checking + * access to a directory. For example, on UNIX systems, checking for + * execute access checks that the Java virtual machine has permission to + * search the directory in order to access file or subdirectories. + * + *
Depending on the implementation, this method may require to read file + * permissions, access control lists, or other file attributes in order to + * check the effective access to the file. Consequently, this method may not + * be atomic with respect to other file system operations. + * + *
Note that the result of this method is immediately outdated, there is + * no guarantee that a subsequent attempt to execute the file will succeed + * (or even that it will access the same file). Care should be taken when + * using this method in security sensitive applications. + * + * @param path + * the path to the file to check + * + * @return {@code true} if the file exists and is executable; {@code false} + * if the file does not exist, execute access would be denied because + * the Java virtual machine has insufficient privileges, or access + * cannot be determined + * + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkExec(String) + * checkExec} is invoked to check execute access to the file. + */ + public static boolean isExecutable(Path path) { + return isAccessible(path, AccessMode.EXECUTE); } + // -- Recursive operations -- + /** * Walks a file tree. * @@ -139,7 +2484,7 @@ public final class Files { * an uncaught error, or runtime exception, then the traversal is terminated * and the error or exception is propagated to the caller of this method. * - *
For each file encountered this method attempts to gets its {@link + *
For each file encountered this method attempts to read its {@link * java.nio.file.attribute.BasicFileAttributes}. If the file is not a * directory then the {@link FileVisitor#visitFile visitFile} method is * invoked with the file attributes. If the file attributes cannot be read, @@ -174,7 +2519,7 @@ public final class Files { * arises when there is an entry in a directory that is an ancestor of the * directory. Cycle detection is done by recording the {@link * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories, - * or if file keys are not available, by invoking the {@link Path#isSameFile + * or if file keys are not available, by invoking the {@link #isSameFile * isSameFile} method to test if a directory is the same file as an * ancestor. When a cycle is detected it is treated as an I/O error, and the * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with @@ -197,25 +2542,27 @@ public final class Files { * that file (or directory). * * @param start - * The starting file + * the starting file * @param options - * Options to configure the traversal + * options to configure the traversal * @param maxDepth - * The maximum number of directory levels to visit + * the maximum number of directory levels to visit * @param visitor - * The file visitor to invoke for each file + * the file visitor to invoke for each file + * + * @return the starting file * * @throws IllegalArgumentException - * If the {@code maxDepth} parameter is negative + * if the {@code maxDepth} parameter is negative * @throws SecurityException * If the security manager denies access to the starting file. * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. * @throws IOException - * If an I/O error is thrown by a visitor method + * if an I/O error is thrown by a visitor method */ - public static void walkFileTree(Path start, + public static Path walkFileTree(Path start, Set
options, int maxDepth, FileVisitor super Path> visitor) @@ -224,6 +2571,7 @@ public final class Files { if (maxDepth < 0) throw new IllegalArgumentException("'maxDepth' is negative"); new FileTreeWalker(options, visitor, maxDepth).walk(start); + return start; } /** @@ -234,11 +2582,15 @@ public final class Files { * + * In other words, it does not follow symbolic links, and visits all levels + * of the file level. * * @param start - * The starting file + * the starting file * @param visitor - * The file visitor to invoke for each file + * the file visitor to invoke for each file + * + * @return the starting file * * @throws SecurityException * If the security manager denies access to the starting file. @@ -246,118 +2598,511 @@ public final class Files { * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. * @throws IOException - * If an I/O error is thrown by a visitor method + * if an I/O error is thrown by a visitor method */ - public static void walkFileTree(Path start, FileVisitor super Path> visitor) + public static Path walkFileTree(Path start, FileVisitor super Path> visitor) throws IOException { - walkFileTree(start, - EnumSet.noneOf(FileVisitOption.class), - Integer.MAX_VALUE, - visitor); + return walkFileTree(start, + EnumSet.noneOf(FileVisitOption.class), + Integer.MAX_VALUE, + visitor); } + + // -- Utility methods for simple usages -- + + // buffer size used for reading and writing + private static final int BUFFER_SIZE = 8192; + /** - * Creates a directory by creating all nonexistent parent directories first. + * Opens a file for reading, returning a {@code BufferedReader} that may be + * used to read text from the file in an efficient manner. Bytes from the + * file are decoded into characters using the specified charset. Reading + * commences at the beginning of the file. * - ** walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor) *The {@code attrs} parameter is an optional array of {@link FileAttribute - * file-attributes} to set atomically when creating the nonexistent - * directories. Each file attribute is identified by its {@link - * FileAttribute#name name}. If more than one attribute of the same name is - * included in the array then all but the last occurrence is ignored. + *
The {@code Reader} methods that read from the file throw {@code + * IOException} if a malformed or unmappable byte sequence is read. * - *
If this method fails, then it may do so after creating some, but not - * all, of the parent directories. + * @param path + * the path to the file + * @param cs + * the charset to use for decoding * - * @param dir - * the directory to create + * @return a new buffered reader, with default buffer size, to read text + * from the file * - * @param attrs - * an optional list of file attributes to set atomically when - * creating the directory + * @throws IOException + * if an I/O error occurs opening the file + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + * + * @see #readAllLines + */ + public static BufferedReader newBufferedReader(Path path, Charset cs) + throws IOException + { + CharsetDecoder decoder = cs.newDecoder(); + Reader reader = new InputStreamReader(newInputStream(path), decoder); + return new BufferedReader(reader); + } + + /** + * Opens or creates a file for writing, returning a {@code BufferedWriter} + * that may be used to write text to the file in an efficient manner. + * The {@code options} parameter specifies how the the file is created or + * opened. If no options are present then this method works as if the {@link + * StandardOpenOption#CREATE CREATE}, {@link + * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link + * StandardOpenOption#WRITE WRITE} options are present. In other words, it + * opens the file for writing, creating the file if it doesn't exist, or + * initially truncating an existing {@link #isRegularFile regular-file} to + * a size of {@code 0} if it exists. + * + *
The {@code Writer} methods to write text throw {@code IOException} + * if the text cannot be encoded using the specified charset. + * + * @param path + * the path to the file + * @param cs + * the charset to use for encoding + * @param options + * options specifying how the file is opened + * + * @return a new buffered writer, with default buffer size, to write text + * to the file * - * @throws UnsupportedOperationException - * if the array contains an attribute that cannot be set atomically - * when creating the directory - * @throws FileAlreadyExistsException - * if {@code dir} exists but is not a directory (optional specific - * exception) * @throws IOException - * if an I/O error occurs + * if an I/O error occurs opening or creating the file + * @throws UnsupportedOperationException + * if an unsupported option is specified * @throws SecurityException - * in the case of the default provider, and a security manager is + * In the case of the default provider, and a security manager is * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked prior to attempting to create a directory and - * its {@link SecurityManager#checkRead(String) checkRead} is - * invoked for each parent directory that is checked. If {@code - * dir} is not an absolute path then its {@link Path#toAbsolutePath - * toAbsolutePath} may need to be invoked to get its absolute path. - * This may invoke the security manager's {@link - * SecurityManager#checkPropertyAccess(String) checkPropertyAccess} - * method to check access to the system property {@code user.dir} + * method is invoked to check write access to the file. * + * @see #write(Path,Iterable,Charset,OpenOption[]) */ - public static void createDirectories(Path dir, FileAttribute>... attrs) + public static BufferedWriter newBufferedWriter(Path path, Charset cs, + OpenOption... options) throws IOException { - // attempt to create the directory - try { - createAndCheckIsDirectory(dir, attrs); - return; - } catch (FileAlreadyExistsException x) { - // file exists and is not a directory - throw x; - } catch (IOException x) { - // parent may not exist or other reason + CharsetEncoder encoder = cs.newEncoder(); + Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder); + return new BufferedWriter(writer); + } + + /** + * Reads all bytes from an input stream and writes them to an output stream. + */ + private static long copy(InputStream source, OutputStream sink) + throws IOException + { + long nread = 0L; + byte[] buf = new byte[BUFFER_SIZE]; + int n; + while ((n = source.read(buf)) > 0) { + sink.write(buf, 0, n); + nread += n; } + return nread; + } - // find existing parent (may require absolute path) - SecurityException se = null; - try { - dir = dir.toAbsolutePath(); - } catch (SecurityException x) { - // don't have permission to get absolute path - se = x; + /** + * Copies all bytes from an input stream to a file. On return, the input + * stream will be at end of stream. + * + *
By default, the copy fails if the target file already exists or is a + * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING + * REPLACE_EXISTING} option is specified, and the target file already exists, + * then it is replaced if it is not a non-empty directory. If the target + * file exists and is a symbolic link, then the symbolic link is replaced. + * In this release, the {@code REPLACE_EXISTING} option is the only option + * required to be supported by this method. Additional options may be + * supported in future releases. + * + *
If an I/O error occurs reading from the input stream or writing to + * the file, then it may do so after the target file has been created and + * after some bytes have been read or written. Consequently the input + * stream may not be at end of stream and may be in an inconsistent state. + * It is strongly recommended that the input stream be promptly closed if an + * I/O error occurs. + * + *
This method may block indefinitely reading from the input stream (or + * writing to the file). The behavior for the case that the input stream is + * asynchronously closed or the thread interrupted during the copy is + * highly input stream and file system provider specific and therefore not + * specified. + * + *
Usage example: Suppose we want to capture a web page and save + * it to a file: + *
+ * Path path = ... + * URI u = URI.create("http://java.sun.com/"); + * try (InputStream in = u.toURL().openStream()) { + * Files.copy(in, path); + * } + *+ * + * @param in + * the input stream to read from + * @param target + * the path to the file + * @param options + * options specifying how the copy should be done + * + * @return the number of bytes read or written + * + * @throws IOException + * if an I/O error occurs when reading or writing + * @throws FileAlreadyExistsException + * if the target file exists but cannot be replaced because the + * {@code REPLACE_EXISTING} option is not specified (optional + * specific exception) + * @throws DirectoryNotEmptyException + * the {@code REPLACE_EXISTING} option is specified but the file + * cannot be replaced because it is a non-empty directory + * (optional specific exception) * + * @throws UnsupportedOperationException + * if {@code options} contains a copy option that is not supported + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. Where the + * {@code REPLACE_EXISTING} option is specified, the security + * manager's {@link SecurityManager#checkDelete(String) checkDelete} + * method is invoked to check that an existing file can be deleted. + */ + public static long copy(InputStream in, Path target, CopyOption... options) + throws IOException + { + // ensure not null before opening file + Objects.nonNull(in); + + // check for REPLACE_EXISTING + boolean replaceExisting = false; + for (CopyOption opt: options) { + if (opt == StandardCopyOption.REPLACE_EXISTING) { + replaceExisting = true; + } else { + if (opt == null) { + throw new NullPointerException("options contains 'null'"); + } else { + throw new UnsupportedOperationException(opt + " not supported"); + } + } } - Path parent = dir.getParent(); - while (parent != null) { + + // attempt to delete an existing file + SecurityException se = null; + if (replaceExisting) { try { - parent.checkAccess(); - break; - } catch (NoSuchFileException x) { - // does not exist + deleteIfExists(target); + } catch (SecurityException x) { + se = x; } - parent = parent.getParent(); } - if (parent == null) { - // unable to find existing parent + + // attempt to create target file. If it fails with + // FileAlreadyExistsException then it may be because the security + // manager prevented us from deleting the file, in which case we just + // throw the SecurityException. + OutputStream ostream; + try { + ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW, + StandardOpenOption.WRITE); + } catch (FileAlreadyExistsException x) { if (se != null) throw se; - throw new IOException("Root directory does not exist"); + // someone else won the race and created the file + throw x; } - // create directories - Path child = parent; - for (Path name: parent.relativize(dir)) { - child = child.resolve(name); - createAndCheckIsDirectory(child, attrs); + // do the copy + try (OutputStream out = ostream) { + return copy(in, out); } } /** - * Attempts to create a directory. Does nothing if the directory already - * exists. + * Copies all bytes from a file to an output stream. + * + *If an I/O error occurs reading from the file or writing to the output + * stream, then it may do so after some bytes have been read or written. + * Consequently the output stream may be in an inconsistent state. It is + * strongly recommended that the output stream be promptly closed if an I/O + * error occurs. + * + *
This method may block indefinitely writing to the output stream (or + * reading from the file). The behavior for the case that the output stream + * is asynchronously closed or the thread interrupted during the copy + * is highly output stream and file system provider specific and therefore + * not specified. + * + *
Note that if the given output stream is {@link java.io.Flushable} + * then its {@link java.io.Flushable#flush flush} method may need to invoked + * after this method completes so as to flush any buffered output. + * + * @param source + * the path to the file + * @param out + * the output stream to write to + * + * @return the number of bytes read or written + * + * @throws IOException + * if an I/O error occurs when reading or writing + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + */ + public static long copy(Path source, OutputStream out) throws IOException { + // ensure not null before opening file + Objects.nonNull(out); + + try (InputStream in = newInputStream(source)) { + return copy(in, out); + } + } + + /** + * Read all the bytes from an input stream. The {@code initialSize} + * parameter indicates the initial size of the byte[] to allocate. */ - private static void createAndCheckIsDirectory(Path dir, FileAttribute>... attrs) + private static byte[] read(InputStream source, int initialSize) throws IOException { - try { - dir.createDirectory(attrs); - } catch (FileAlreadyExistsException x) { - boolean isDirectory = Attributes - .readBasicFileAttributes(dir, LinkOption.NOFOLLOW_LINKS).isDirectory(); - if (!isDirectory) - throw x; + int capacity = initialSize; + byte[] buf = new byte[capacity]; + int nread = 0; + int rem = buf.length; + int n; + // read to EOF which may read more or less than initialSize (eg: file + // is truncated while we are reading) + while ((n = source.read(buf, nread, rem)) > 0) { + nread += n; + rem -= n; + assert rem >= 0; + if (rem == 0) { + // need larger buffer + int newCapacity = capacity << 1; + if (newCapacity < 0) { + if (capacity == Integer.MAX_VALUE) + throw new OutOfMemoryError("Required array size too large"); + newCapacity = Integer.MAX_VALUE; + } + rem = newCapacity - capacity; + buf = Arrays.copyOf(buf, newCapacity); + capacity = newCapacity; + } + } + return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); + } + + /** + * Read all the bytes from a file. The method ensures that the file is + * closed when all bytes have been read or an I/O error, or other runtime + * exception, is thrown. + * + *
Note that this method is intended for simple cases where it is + * convenient to read all bytes into a byte array. It is not intended for + * reading in large files. + * + * @param path + * the path to the file + * + * @return a byte array containing the bytes read from the file + * + * @throws IOException + * if an I/O error occurs reading from the stream + * @throws OutOfMemoryError + * if an array of the required size cannot be allocated, for + * example the file is larger that {@code 2GB} + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + */ + public static byte[] readAllBytes(Path path) throws IOException { + long size = size(path); + if (size > (long)Integer.MAX_VALUE) + throw new OutOfMemoryError("Required array size too large"); + + try (InputStream in = newInputStream(path)) { + return read(in, (int)size); + } + } + + /** + * Read all lines from a file. This method ensures that the file is + * closed when all bytes have been read or an I/O error, or other runtime + * exception, is thrown. Bytes from the file are decoded into characters + * using the specified charset. + * + *
This method recognizes the following as line terminators: + *
+ *
+ *- + *
\u000D
followed by\u000A
, + * CARRIAGE RETURN followed by LINE FEED- + *
\u000A
, LINE FEED- + *
\u000D
, CARRIAGE RETURNAdditional Unicode line terminators may be recognized in future + * releases. + * + *
Note that this method is intended for simple cases where it is + * convenient to read all lines in a single operation. It is not intended + * for reading in large files. + * + * @param path + * the path to the file + * @param cs + * the charset to use for decoding + * + * @return the lines from the file as a {@code List}; whether the {@code + * List} is modifiable or not is implementation dependent and + * therefore not specified + * + * @throws IOException + * if an I/O error occurs reading from the file or a malformed or + * unmappable byte sequence is read + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} + * method is invoked to check read access to the file. + * + * @see #newBufferedReader + */ + public static List
- * + *readAllLines(Path path, Charset cs) + throws IOException + { + try (BufferedReader reader = newBufferedReader(path, cs)) { + List result = new ArrayList<>(); + for (;;) { + String line = reader.readLine(); + if (line == null) + break; + result.add(line); + } + return result; + } + } + + /** + * Writes bytes to a file. The {@code options} parameter specifies how the + * the file is created or opened. If no options are present then this method + * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link + * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link + * StandardOpenOption#WRITE WRITE} options are present. In other words, it + * opens the file for writing, creating the file if it doesn't exist, or + * initially truncating an existing {@link #isRegularFile regular-file} to + * a size of {@code 0}. All bytes in the byte array are written to the file. + * The method ensures that the file is closed when all bytes have been + * written (or an I/O error or other runtime exception is thrown). If an I/O + * error occurs then it may do so after the file has created or truncated, + * or after some bytes have been written to the file. + * + * Usage example: By default the method creates a new file or + * overrides an existing file. Suppose you instead want to append bytes + * to an existing file: + *
+ * Path path = ... + * byte[] bytes = ... + * Files.write(path, bytes, StandardOpenOption.APPEND); + *+ * + * @param path + * the path to the file + * @param bytes + * the byte array with the bytes to write + * @param options + * options specifying how the file is opened + * + * @return the path + * + * @throws IOException + * if an I/O error occurs writing to or creating the file + * @throws UnsupportedOperationException + * if an unsupported option is specified + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. + */ + public static Path write(Path path, byte[] bytes, OpenOption... options) + throws IOException + { + // ensure bytes is not null before opening file + Objects.nonNull(bytes); + + try (OutputStream out = Files.newOutputStream(path, options)) { + int len = bytes.length; + int rem = len; + while (rem > 0) { + int n = Math.min(rem, BUFFER_SIZE); + out.write(bytes, (len-rem), n); + rem -= n; + } + } + return path; + } + + /** + * Write lines of text to a file. Each line is a char sequence and is + * written to the file in sequence with each line terminated by the + * platform's line separator, as defined by the system property {@code + * line.separator}. Characters are encoded into bytes using the specified + * charset. + * + *The {@code options} parameter specifies how the the file is created + * or opened. If no options are present then this method works as if the + * {@link StandardOpenOption#CREATE CREATE}, {@link + * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link + * StandardOpenOption#WRITE WRITE} options are present. In other words, it + * opens the file for writing, creating the file if it doesn't exist, or + * initially truncating an existing {@link #isRegularFile regular-file} to + * a size of {@code 0}. The method ensures that the file is closed when all + * lines have been written (or an I/O error or other runtime exception is + * thrown). If an I/O error occurs then it may do so after the file has + * created or truncated, or after some bytes have been written to the file. + * + * @param path + * the path to the file + * @param lines + * an object to iterate over the char sequences + * @param cs + * the charset to use for encoding + * @param options + * options specifying how the file is opened + * + * @return the path + * + * @throws IOException + * if an I/O error occurs writing to or creating the file, or the + * text cannot be encoded using the specified charset + * @throws UnsupportedOperationException + * if an unsupported option is specified + * @throws SecurityException + * In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkWrite(String) checkWrite} + * method is invoked to check write access to the file. + */ + public static Path write(Path path, Iterable extends CharSequence> lines, + Charset cs, OpenOption... options) + throws IOException + { + // ensure lines is not null before opening file + Objects.nonNull(lines); + CharsetEncoder encoder = cs.newEncoder(); + OutputStream out = newOutputStream(path, options); + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) { + for (CharSequence line: lines) { + writer.append(line); + writer.newLine(); + } } + return path; } } diff --git a/src/share/classes/java/nio/file/LinkOption.java b/src/share/classes/java/nio/file/LinkOption.java index 7c8d97d4c3f272504180411954dd6b9817ccdec1..13a42ef7143a2f7e3ebeff46c5445c88e7b37674 100644 --- a/src/share/classes/java/nio/file/LinkOption.java +++ b/src/share/classes/java/nio/file/LinkOption.java @@ -35,8 +35,8 @@ public enum LinkOption implements OpenOption, CopyOption { /** * Do not follow symbolic links. * - * @see FileRef#getFileAttributeView(Class,LinkOption[]) - * @see Path#copyTo + * @see Files#getFileAttributeView(Path,Class,LinkOption[]) + * @see Files#copy * @see SecureDirectoryStream#newByteChannel */ NOFOLLOW_LINKS; diff --git a/src/share/classes/java/nio/file/LinkPermission.java b/src/share/classes/java/nio/file/LinkPermission.java index 25d799f8c744d7316bc536f4f8eb293ab3ecb43d..161d1b9d7af312e3d957b4c23ecd149d0ad8c6aa 100644 --- a/src/share/classes/java/nio/file/LinkPermission.java +++ b/src/share/classes/java/nio/file/LinkPermission.java @@ -59,8 +59,8 @@ import java.security.BasicPermission; * * @since 1.7 * - * @see Path#createLink - * @see Path#createSymbolicLink + * @see Files#createLink + * @see Files#createSymbolicLink */ public final class LinkPermission extends BasicPermission { static final long serialVersionUID = -1441492453772213220L; diff --git a/src/share/classes/java/nio/file/OpenOption.java b/src/share/classes/java/nio/file/OpenOption.java index aae5e27911dcd21f13ab7eaca9b619655d411545..522d5ddc4f02cb67867d1f4a19d0e82eb6d4dd3d 100644 --- a/src/share/classes/java/nio/file/OpenOption.java +++ b/src/share/classes/java/nio/file/OpenOption.java @@ -29,8 +29,8 @@ package java.nio.file; * An object that configures how to open or create a file. * *
Objects of this type are used by methods such as {@link - * Path#newOutputStream(OpenOption[]) newOutputStream}, {@link - * Path#newByteChannel newByteChannel}, {@link + * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link + * Files#newByteChannel newByteChannel}, {@link * java.nio.channels.FileChannel#open FileChannel.open}, and {@link * java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open} * when opening or creating a file. diff --git a/src/share/classes/java/nio/file/Path.java b/src/share/classes/java/nio/file/Path.java index b41e03f91beab98a35f1fdb02b191c7caa0db5f8..85436b01d9ae47eb3cc0c29d20de56c378b11f61 100644 --- a/src/share/classes/java/nio/file/Path.java +++ b/src/share/classes/java/nio/file/Path.java @@ -25,147 +25,95 @@ package java.nio.file; -import java.nio.file.attribute.*; -import java.nio.channels.SeekableByteChannel; +import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.net.URI; import java.util.Iterator; -import java.util.Set; /** - * A file reference that locates a file using a system dependent path. The file - * is not required to exist. + * An object that may be used to locate a file in a file system. It will + * typically represent a system dependent file path. * - *
On many platforms a path is the means to locate and access files - * in a file system. A path is hierarchical and composed of a sequence of - * directory and file name elements separated by a special separator or - * delimiter. - * - *
Path operations
- * - *A system dependent path represented by this class is conceptually a - * sequence of name elements and optionally a root component. The name - * that is farthest from the root of the directory hierarchy is the - * name of a file or directory. The other elements are directory names. The root - * component typically identifies a file system hierarchy. A {@code Path} can - * represent a root, a root and a sequence of names, or simply one or more name - * elements. It defines the {@link #getName() getName}, {@link #getParent - * getParent}, {@link #getRoot getRoot}, and {@link #subpath subpath} methods - * to access the components or a subsequence of its name elements. + *
A {@code Path} represents a path that is hierarchical and composed of a + * sequence of directory and file name elements separated by a special separator + * or delimiter. A root component, that identifies a file system + * hierarchy, may also be present. The name element that is farthest + * from the root of the directory hierarchy is the name of a file or directory. + * The other name elements are directory names. A {@code Path} can represent a + * root, a root and a sequence of names, or simply one or more name elements. + * A {@code Path} is considered to be an empty path if it consists + * solely of one name element that is empty. Accessing a file using an + * empty path is equivalent to accessing the default directory of the + * file system. {@code Path} defines the {@link #getFileName() getFileName}, + * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath + * subpath} methods to access the path components or a subsequence of its name + * elements. * *
In addition to accessing the components of a path, a {@code Path} also - * defines {@link #resolve(Path) resolve} and {@link #relativize relativize} - * operations. Paths can also be {@link #compareTo compared}, and tested - * against each other using using the {@link #startsWith startsWith} and {@link - * #endsWith endWith} methods. - * - *
File operations
- * - *A {@code Path} is either absolute or relative. An - * absolute path is complete in that does not need to be combined with another - * path in order to locate a file. All operations on relative paths are first - * resolved against a file system's default directory as if by invoking the - * {@link #toAbsolutePath toAbsolutePath} method. - * - *
In addition to the operations defined by the {@link FileRef} interface, - * this class defines the following operations: + * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path) + * resolveSibling} methods to combine paths. The {@link #relativize relativize} + * method that can be used to construct a relative path between two paths. + * Paths can be {@link #compareTo compared}, and tested against each other using + * the {@link #startsWith startsWith} and {@link #endsWith endWith} methods. * - *
- *
- - *
The {@link #newByteChannel newByteChannel} method - * may be used to open a file and obtain a byte channel for reading or - * writing.
- - *
Files may be {@link #createFile(FileAttribute[]) created}, or - * directories may be {@link #createDirectory(FileAttribute[]) created}. - *
- - *
The {@link #delete delete} method may be used to delete a file. - *
- - *
The {@link #checkAccess checkAccess} method may be used to check - * the existence or accessibility of a file.
- - *
The {@link #isSameFile isSameFile} method may be used to test if - * two file references locate the same file.
- - *
The {@link #getFileStore getFileStore} method may be used to - * obtain the {@link FileStore} representing the storage where a file is - * located.
- - *
Directories can be {@link #newDirectoryStream opened} so as to - * iterate over the entries in the directory.
- - *
Files can be {@link #copyTo(Path,CopyOption[]) copied} or - * {@link #moveTo(Path,CopyOption[]) moved}.
- - *
Symbolic links may be {@link #createSymbolicLink created}, or the - * target of a symbolic link may be {@link #readSymbolicLink read}.
The {@link #toRealPath real} path of an existing file may be - * obtained.
This interface extends {@link Watchable} interface so that a directory + * located by a path can be {@link #register registered} with a {@link + * WatchService} and entries in the directory watched.
* - *This class implements {@link Watchable} interface so that a directory - * located by a path can be {@link #register registered} with a {@link WatchService}. - * and entries in the directory watched. + *
WARNING: This interface is only intended to be implemented by + * those developing custom file system implementations. Methods may be added to + * this interface in future releases.
* - *File attributes
- * - * In addition to the {@link #setAttribute setAttribute} and {@link #getAttribute - * getAttribute} methods, the {@code - * java.nio.file.attribute} package provides type-safe and efficient access - * to file attributes or meta-data associated with files. The {@link - * Attributes Attributes} class defines methods that operate on or return file - * attributes. For example, the file type, size, timestamps, and other - * basic meta-data are obtained, in bulk, by invoking the {@link - * Attributes#readBasicFileAttributes Attributes.readBasicFileAttributes} method: + *Accessing Files
+ *Paths may be used with the {@link Files} class to operate on files, + * directories, and other types of files. For example, suppose we want a {@link + * java.io.BufferedReader} to read text from a file "{@code access.log}". The + * file is located in a directory "{@code logs}" relative to the current working + * directory and is UTF-8 encoded. *
- * Path file = ... - * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file); + * Path path = FileSystems.getDefault().getPath("logs", "access.log"); + * BufferReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8")); ** *Interoperability
- * - *Paths created by file systems associated with the default {@link + *
Paths associated with the default {@link * java.nio.file.spi.FileSystemProvider provider} are generally interoperable * with the {@link java.io.File java.io.File} class. Paths created by other * providers are unlikely to be interoperable with the abstract path names - * represented by {@code java.io.File}. The {@link java.io.File#toPath - * File.toPath} method may be used to obtain a {@code Path} from the abstract - * path name represented by a {@code java.io.File java.io.File} object. The - * resulting {@code Path} can be used to operate on the same file as the {@code - * java.io.File} object. - * - *
Path objects created by file systems associated with the default - * provider are interoperable with objects created by other file systems created - * by the same provider. Path objects created by file systems associated with - * other providers may not be interoperable with other file systems created by - * the same provider. The reasons for this are provider specific. + * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath} + * method may be used to obtain a {@code Path} from the abstract path name + * represented by a {@code java.io.File} object. The resulting {@code Path} can + * be used to operate on the same file as the {@code java.io.File} object. In + * addition, the {@link #toFile toFile} method is useful to construct a {@code + * File} from the {@code String} representation of a {@code Path}. * *
Concurrency
Instances of this class are immutable and safe for use by multiple concurrent - * threads. + *
Implementations of this interface are immutable and safe for use by + * multiple concurrent threads. * * @since 1.7 + * @see Paths */ -public abstract class Path - implements FileRef, Comparable
, Iterable , Watchable +public interface Path + extends Comparable , Iterable , Watchable { - /** - * Initializes a new instance of this class. - */ - protected Path() { } - /** * Returns the file system that created this object. * * @return the file system that created this object */ - public abstract FileSystem getFileSystem(); + FileSystem getFileSystem(); /** * Tells whether or not this path is absolute. * - * An absolute path is complete in that it doesn't need to be - * combined with other path information in order to locate a file. + *
An absolute path is complete in that it doesn't need to be combined + * with other path information in order to locate a file. * * @return {@code true} if, and only if, this path is absolute */ - public abstract boolean isAbsolute(); + boolean isAbsolute(); /** * Returns the root component of this path as a {@code Path} object, @@ -174,17 +122,17 @@ public abstract class Path * @return a path representing the root component of this path, * or {@code null} */ - public abstract Path getRoot(); + Path getRoot(); /** - * Returns the name of the file or directory denoted by this path. The - * file name is the farthest element from the root in the directory - * hierarchy. + * Returns the name of the file or directory denoted by this path as a + * {@code Path} object. The file name is the farthest element from + * the root in the directory hierarchy. * * @return a path representing the name of the file or directory, or * {@code null} if this path has zero elements */ - public abstract Path getName(); + Path getFileName(); /** * Returns the parent path, or {@code null} if this path does not @@ -209,7 +157,7 @@ public abstract class Path * * @return a path representing the path's parent */ - public abstract Path getParent(); + Path getParent(); /** * Returns the number of name elements in the path. @@ -217,10 +165,10 @@ public abstract class Path * @return the number of elements in the path, or {@code 0} if this path * only represents a root component */ - public abstract int getNameCount(); + int getNameCount(); - /** - * Returns a name element of this path. + /** + * Returns a name element of this path as a {@code Path} object. * *
The {@code index} parameter is the index of the name element to return. * The element that is closest to the root in the directory hierarchy @@ -237,7 +185,7 @@ public abstract class Path * equal to the number of elements, or this path has zero name * elements */ - public abstract Path getName(int index); + Path getName(int index); /** * Returns a relative {@code Path} that is a subsequence of the name @@ -264,7 +212,7 @@ public abstract class Path * the number of elements. If {@code endIndex} is less than or * equal to {@code beginIndex}, or larger than the number of elements. */ - public abstract Path subpath(int beginIndex, int endIndex); + Path subpath(int beginIndex, int endIndex); /** * Tests if this path starts with the given path. @@ -286,7 +234,25 @@ public abstract class Path * @return {@code true} if this path starts with the given path; otherwise * {@code false} */ - public abstract boolean startsWith(Path other); + boolean startsWith(Path other); + + /** + * Tests if this path starts with a {@code Path}, constructed by converting + * the given path string, in exactly the manner specified by the {@link + * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path + * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It + * does not start with "{@code f}" or "{@code fo}". + * + * @param other + * the given path string + * + * @return {@code true} if this path starts with the given path; otherwise + * {@code false} + * + * @throws InvalidPathException + * If the path string cannot be converted to a Path. + */ + boolean startsWith(String other); /** * Tests if this path ends with the given path. @@ -310,7 +276,25 @@ public abstract class Path * @return {@code true} if this path ends with the given path; otherwise * {@code false} */ - public abstract boolean endsWith(Path other); + boolean endsWith(Path other); + + /** + * Tests if this path ends with a {@code Path}, constructed by converting + * the given path string, in exactly the manner specified by the {@link + * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path + * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does + * not end with "{@code r}" or "{@code /bar}". + * + * @param other + * the given path string + * + * @return {@code true} if this path starts with the given path; otherwise + * {@code false} + * + * @throws InvalidPathException + * If the path string cannot be converted to a Path. + */ + boolean endsWith(String other); /** * Returns a path that is this path with redundant name elements eliminated. @@ -330,14 +314,14 @@ public abstract class Path * path may result in the path that locates a different file than the original * path. This can arise when the preceding name is a symbolic link. * - * @return the resulting path, or this path if it does not contain - * redundant name elements, or {@code null} if this path does not - * have a root component and all name elements are redundant + * @return the resulting path or this path if it does not contain + * redundant name elements; an empty path is returned if this path + * does have a root component and all name elements are redundant * * @see #getParent * @see #toRealPath */ - public abstract Path normalize(); + Path normalize(); // -- resolution and relativization -- @@ -346,28 +330,31 @@ public abstract class Path * *
If the {@code other} parameter is an {@link #isAbsolute() absolute} * path then this method trivially returns {@code other}. If {@code other} - * is {@code null} then this path is returned. Otherwise this method - * considers this path to be a directory and resolves the given path - * against this path. In the simplest case, the given path does not have - * a {@link #getRoot root} component, in which case this method joins - * the given path to this path and returns a resulting path that {@link - * #endsWith ends} with the given path. Where the given path has a root - * component then resolution is highly implementation dependent and therefore - * unspecified. + * is an empty path then this method trivially returns this path. + * Otherwise this method considers this path to be a directory and resolves + * the given path against this path. In the simplest case, the given path + * does not have a {@link #getRoot root} component, in which case this method + * joins the given path to this path and returns a resulting path + * that {@link #endsWith ends} with the given path. Where the given path has + * a root component then resolution is highly implementation dependent and + * therefore unspecified. * * @param other - * the path to resolve against this path; can be {@code null} + * the path to resolve against this path * * @return the resulting path * * @see #relativize */ - public abstract Path resolve(Path other); + Path resolve(Path other); /** * Converts a given path string to a {@code Path} and resolves it against * this {@code Path} in exactly the manner specified by the {@link - * #resolve(Path) resolve} method. + * #resolve(Path) resolve} method. For example, suppose that the name + * separator is "{@code /}" and a path represents "{@code foo/bar}", then + * invoking this method with the path string "{@code gus}" will result in + * the {@code Path} "{@code foo/bar/gus}". * * @param other * the path string to resolve against this path @@ -375,11 +362,49 @@ public abstract class Path * @return the resulting path * * @throws InvalidPathException - * If the path string cannot be converted to a Path. + * if the path string cannot be converted to a Path. + * + * @see FileSystem#getPath + */ + Path resolve(String other); + + /** + * Resolves the given path against this path's {@link #getParent parent} + * path. This is useful where a file name needs to be replaced with + * another file name. For example, suppose that the name separator is + * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking + * this method with the {@code Path} "{@code bar}" will result in the {@code + * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path, + * or {@code other} is {@link #isAbsolute() absolute}, then this method + * returns {@code other}. If {@code other} is an empty path then this method + * returns this path's parent, or where this path doesn't have a parent, the + * empty path. + * + * @param other + * the path to resolve against this path's parent + * + * @return the resulting path + * + * @see #resolve(Path) + */ + Path resolveSibling(Path other); + + /** + * Converts a given path string to a {@code Path} and resolves it against + * this path's {@link #getParent parent} path in exactly the manner + * specified by the {@link #resolveSibling(Path) resolveSibling} method. + * + * @param other + * the path string to resolve against this path's parent + * + * @return the resulting path + * + * @throws InvalidPathException + * if the path string cannot be converted to a Path. * * @see FileSystem#getPath */ - public abstract Path resolve(String other); + Path resolveSibling(String other); /** * Constructs a relative path between this path and a given path. @@ -395,17 +420,17 @@ public abstract class Path * constructed if only one of the paths have a root component. Where both * paths have a root component then it is implementation dependent if a * relative path can be constructed. If this path and the given path are - * {@link #equals equal} then {@code null} is returned. + * {@link #equals equal} then an empty path is returned. * - *
For any two paths p and q, where q does not have - * a root component, + *
For any two {@link #normalize normalized} paths p and + * q, where q does not have a root component, *
* p.relativize(p.resolve(q)).equals(q) ** *When symbolic links are supported, then whether the resulting path, * when resolved against this path, yields a path that can be used to locate - * the {@link #isSameFile same} file as {@code other} is implementation + * the {@link Files#isSameFile same} file as {@code other} is implementation * dependent. For example, if this path is {@code "/a/b"} and the given * path is {@code "/a/x"} then the resulting relative path may be {@code * "../x"}. If {@code "b"} is a symbolic link then is implementation @@ -414,185 +439,14 @@ public abstract class Path * @param other * the path to relativize against this path * - * @return the resulting relative path, or {@code null} if both paths are + * @return the resulting relative path, or an empty path if both paths are * equal * * @throws IllegalArgumentException * if {@code other} is not a {@code Path} that can be relativized * against this path */ - public abstract Path relativize(Path other); - - // -- file operations -- - - /** - * Deletes the file located by this path. - * - *
An implementation may require to examine the file to determine if the - * file is a directory. Consequently this method may not be atomic with respect - * to other file system operations. If the file is a symbolic link then the - * symbolic link itself, not the final target of the link, is deleted. - * - *
If the file is a directory then the directory must be empty. In some - * implementations a directory has entries for special files or links that - * are created when the directory is created. In such implementations a - * directory is considered empty when only the special entries exist. - * - *
On some operating systems it may not be possible to remove a file when - * it is open and in use by this Java virtual machine or other programs. - * - * @throws NoSuchFileException - * if the file does not exist (optional specific exception) - * @throws DirectoryNotEmptyException - * if the file is a directory and could not otherwise be deleted - * because the directory is not empty (optional specific - * exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkDelete(String)} method - * is invoked to check delete access to the file - */ - public abstract void delete() throws IOException; - - /** - * Deletes the file located by this path, if it exists. - * - *
As with the {@link #delete delete()} method, an implementation may - * need to examine the file to determine if the file is a directory. - * Consequently this method may not be atomic with respect to other file - * system operations. If the file is a symbolic link, then the symbolic - * link itself, not the final target of the link, is deleted. - * - *
If the file is a directory then the directory must be empty. In some - * implementations a directory has entries for special files or links that - * are created when the directory is created. In such implementations a - * directory is considered empty when only the special entries exist. - * - *
On some operating systems it may not be possible to remove a file when - * it is open and in use by this Java virtual machine or other programs. - * - * @throws DirectoryNotEmptyException - * if the file is a directory and could not otherwise be deleted - * because the directory is not empty (optional specific - * exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkDelete(String)} method - * is invoked to check delete access to the file. - */ - public abstract void deleteIfExists() throws IOException; - - /** - * Creates a symbolic link to a target (optional operation). - * - *
The {@code target} parameter is the target of the link. It may be an - * {@link Path#isAbsolute absolute} or relative path and may not exist. When - * the target is a relative path then file system operations on the resulting - * link are relative to the path of the link. - * - *
The {@code attrs} parameter is an optional array of {@link FileAttribute - * attributes} to set atomically when creating the link. Each attribute is - * identified by its {@link FileAttribute#name name}. If more than one attribute - * of the same name is included in the array then all but the last occurrence - * is ignored. - * - *
Where symbolic links are supported, but the underlying {@link FileStore} - * does not support symbolic links, then this may fail with an {@link - * IOException}. Additionally, some operating systems may require that the - * Java virtual machine be started with implementation specific privileges to - * create symbolic links, in which case this method may throw {@code IOException}. - * - * @param target - * the target of the symbolic link - * @param attrs - * the array of attributes to set atomically when creating the - * symbolic link - * - * @return this path - * - * @throws UnsupportedOperationException - * if the implementation does not support symbolic links or the - * array contains an attribute that cannot be set atomically when - * creating the symbolic link - * @throws FileAlreadyExistsException - * if a file with the name already exists (optional specific - * exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager - * is installed, it denies {@link LinkPermission}("symbolic") - * or its {@link SecurityManager#checkWrite(String) checkWrite} - * method denies write access to the path of the symbolic link. - */ - public abstract Path createSymbolicLink(Path target, FileAttribute>... attrs) - throws IOException; - - /** - * Creates a new link (directory entry) for an existing file (optional - * operation). - * - *
This path locates the directory entry to create. The {@code existing} - * parameter is the path to an existing file. This method creates a new - * directory entry for the file so that it can be accessed using this path. - * On some file systems this is known as creating a "hard link". Whether the - * file attributes are maintained for the file or for each directory entry - * is file system specific and therefore not specified. Typically, a file - * system requires that all links (directory entries) for a file be on the - * same file system. Furthermore, on some platforms, the Java virtual machine - * may require to be started with implementation specific privileges to - * create hard links or to create links to directories. - * - * @param existing - * a reference to an existing file - * - * @return this path - * - * @throws UnsupportedOperationException - * if the implementation does not support adding an existing file - * to a directory - * @throws FileAlreadyExistsException - * if the entry could not otherwise be created because a file of - * that name already exists (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager - * is installed, it denies {@link LinkPermission}("hard") - * or its {@link SecurityManager#checkWrite(String) checkWrite} - * method denies write access to both this path and the path of the - * existing file. - */ - public abstract Path createLink(Path existing) throws IOException; - - /** - * Reads the target of a symbolic link (optional operation). - * - *
If the file system supports symbolic - * links then this method is used to read the target of the link, failing - * if the file is not a symbolic link. The target of the link need not exist. - * The returned {@code Path} object will be associated with the same file - * system as this {@code Path}. - * - * @return a {@code Path} object representing the target of the link - * - * @throws UnsupportedOperationException - * if the implementation does not support symbolic links - * @throws NotLinkException - * if the target could otherwise not be read because the file - * is not a symbolic link (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager - * is installed, it checks that {@code FilePermission} has been - * granted with the "{@code readlink}" action to read the link. - */ - public abstract Path readSymbolicLink() throws IOException; + Path relativize(Path other); /** * Returns a URI to represent this path. @@ -647,7 +501,7 @@ public abstract class Path * is installed, the {@link #toAbsolutePath toAbsolutePath} method * throws a security exception. */ - public abstract URI toUri(); + URI toUri(); /** * Returns a {@code Path} object representing the absolute path of this @@ -670,14 +524,14 @@ public abstract class Path * checkPropertyAccess} method is invoked to check access to the * system property {@code user.dir} */ - public abstract Path toAbsolutePath(); + Path toAbsolutePath(); /** * Returns the real path of an existing file. * *
The precise definition of this method is implementation dependent but * in general it derives from this path, an {@link #isAbsolute absolute} - * path that locates the {@link #isSameFile same} file as this path, but + * path that locates the {@link Files#isSameFile same} file as this path, but * with name elements that represent the actual name of the directories * and the file. For example, where filename comparisons on a file system * are case insensitive then the name elements represent the names in their @@ -713,756 +567,25 @@ public abstract class Path * checkPropertyAccess} method is invoked to check access to the * system property {@code user.dir} */ - public abstract Path toRealPath(boolean resolveLinks) throws IOException; - - /** - * Copy the file located by this path to a target location. - * - *
This method copies the file located by this {@code Path} to the - * target location with the {@code options} parameter specifying how the - * copy is performed. By default, the copy fails if the target file already - * exists, except if the source and target are the {@link #isSameFile same} - * file, in which case this method has no effect. File attributes are not - * required to be copied to the target file. If symbolic links are supported, - * and the file is a symbolic link, then the final target of the link is copied. - * If the file is a directory then it creates an empty directory in the target - * location (entries in the directory are not copied). This method can be - * used with the {@link Files#walkFileTree Files.walkFileTree} utility - * method to copy a directory and all entries in the directory, or an entire - * file-tree where required. - * - *
The {@code options} parameter is an array of options and may contain - * any of the following: - * - *
- *
- * - *- * Option Description - * - *{@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} - *If the target file exists, then the target file is replaced if it - * is not a non-empty directory. If the target file exists and is a - * symbolic link, then the symbolic link itself, not the target of - * the link, is replaced. - *- * - *{@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} - *Attempts to copy the file attributes associated with this file to - * the target file. The exact file attributes that are copied is platform - * and file system dependent and therefore unspecified. Minimally, the - * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is - * copied to the target file if supported by both the source and target - * file store. Copying of file timestamps may result in precision - * loss. - *- * - *{@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} - *Symbolic links are not followed. If the file, located by this path, - * is a symbolic link, then the symbolic link itself, not the target of - * the link, is copied. It is implementation specific if file attributes - * can be copied to the new link. In other words, the {@code - * COPY_ATTRIBUTES} option may be ignored when copying a symbolic link. - *An implementation of this interface may support additional - * implementation specific options. - * - *
Copying a file is not an atomic operation. If an {@link IOException} - * is thrown then it possible that the target file is incomplete or some of - * its file attributes have not been copied from the source file. When the - * {@code REPLACE_EXISTING} option is specified and the target file exists, - * then the target file is replaced. The check for the existence of the file - * and the creation of the new file may not be atomic with respect to other - * file system activities. - * - * @param target - * the target location - * @param options - * options specifying how the copy should be done - * - * @return the target - * - * @throws UnsupportedOperationException - * if the array contains a copy option that is not supported - * @throws FileAlreadyExistsException - * if the target file exists and cannot be replaced because the - * {@code REPLACE_EXISTING} option is not specified, or the target - * file is a non-empty directory (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the source file, the - * {@link SecurityManager#checkWrite(String) checkWrite} is invoked - * to check write access to the target file. If a symbolic link is - * copied the security manager is invoked to check {@link - * LinkPermission}{@code ("symbolic")}. - */ - public abstract Path copyTo(Path target, CopyOption... options) - throws IOException; - - /** - * Move or rename the file located by this path to a target location. - * - *
By default, this method attempts to move the file to the target - * location, failing if the target file exists except if the source and - * target are the {@link #isSameFile same} file, in which case this method - * has no effect. If the file is a symbolic link then the symbolic link - * itself, not the target of the link, is moved. This method may be - * invoked to move an empty directory. In some implementations a directory - * has entries for special files or links that are created when the - * directory is created. In such implementations a directory is considered - * empty when only the special entries exist. When invoked to move a - * directory that is not empty then the directory is moved if it does not - * require moving the entries in the directory. For example, renaming a - * directory on the same {@link FileStore} will usually not require moving - * the entries in the directory. When moving a directory requires that its - * entries be moved then this method fails (by throwing an {@code - * IOException}). To move a file tree may involve copying rather - * than moving directories and this can be done using the {@link - * #copyTo copyTo} method in conjunction with the {@link - * Files#walkFileTree Files.walkFileTree} utility method. - * - *
The {@code options} parameter is an array of options and may contain - * any of the following: - * - *
- *
- * - *- * Option Description - * - *{@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} - *If the target file exists, then the target file is replaced if it - * is not a non-empty directory. If the target file exists and is a - * symbolic link, then the symbolic link itself, not the target of - * the link, is replaced. - *- * {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} - *The move is performed as an atomic file system operation and all - * other options are ignored. If the target file exists then it is - * implementation specific if the existing file is replaced or this method - * fails by throwing an {@link IOException}. If the move cannot be - * performed as an atomic file system operation then {@link - * AtomicMoveNotSupportedException} is thrown. This can arise, for - * example, when the target location is on a different {@code FileStore} - * and would require that the file be copied, or target location is - * associated with a different provider to this object. - *An implementation of this interface may support additional - * implementation specific options. - * - *
Where the move requires that the file be copied then the {@link - * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the - * new file. An implementation may also attempt to copy other file - * attributes but is not required to fail if the file attributes cannot be - * copied. When the move is performed as a non-atomic operation, and a {@code - * IOException} is thrown, then the state of the files is not defined. The - * original file and the target file may both exist, the target file may be - * incomplete or some of its file attributes may not been copied from the - * original file. - * - * @param target - * the target location - * @param options - * options specifying how the move should be done - * - * @return the target - * - * @throws UnsupportedOperationException - * if the array contains a copy option that is not supported - * @throws FileAlreadyExistsException - * if the target file exists and cannot be replaced because the - * {@code REPLACE_EXISTING} option is not specified, or the target - * file is a non-empty directory - * @throws AtomicMoveNotSupportedException - * if the options array contains the {@code ATOMIC_MOVE} option but - * the file cannot be moved as an atomic file system operation. - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked to check write access to both the source and - * target file. - */ - public abstract Path moveTo(Path target, CopyOption... options) - throws IOException; - - /** - * Opens the directory referenced by this object, returning a {@code - * DirectoryStream} to iterate over all entries in the directory. The - * elements returned by the directory stream's {@link DirectoryStream#iterator - * iterator} are of type {@code Path}, each one representing an entry in the - * directory. The {@code Path} objects are obtained as if by {@link - * #resolve(Path) resolving} the name of the directory entry against this - * path. - * - *
The directory stream's {@code close} method should be invoked after - * iteration is completed so as to free any resources held for the open - * directory. - * - *
When an implementation supports operations on entries in the - * directory that execute in a race-free manner then the returned directory - * stream is a {@link SecureDirectoryStream}. - * - * @return a new and open {@code DirectoryStream} object - * - * @throws NotDirectoryException - * if the file could not otherwise be opened because it is not - * a directory (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the directory. - */ - public abstract DirectoryStream
newDirectoryStream() - throws IOException; - - /** - * Opens the directory referenced by this object, returning a {@code - * DirectoryStream} to iterate over the entries in the directory. The - * elements returned by the directory stream's {@link DirectoryStream#iterator - * iterator} are of type {@code Path}, each one representing an entry in the - * directory. The {@code Path} objects are obtained as if by {@link - * #resolve(Path) resolving} the name of the directory entry against this - * path. The entries returned by the iterator are filtered by matching the - * {@code String} representation of their file names against the given - * globbing pattern. - * - * For example, suppose we want to iterate over the files ending with - * ".java" in a directory: - *
- * Path dir = ... - * DirectoryStream<Path> stream = dir.newDirectoryStream("*.java"); - *- * - *The globbing pattern is specified by the {@link - * FileSystem#getPathMatcher getPathMatcher} method. - * - *
The directory stream's {@code close} method should be invoked after - * iteration is completed so as to free any resources held for the open - * directory. - * - *
When an implementation supports operations on entries in the - * directory that execute in a race-free manner then the returned directory - * stream is a {@link SecureDirectoryStream}. - * - * @param glob - * the glob pattern - * - * @return a new and open {@code DirectoryStream} object - * - * @throws java.util.regex.PatternSyntaxException - * if the pattern is invalid - * @throws NotDirectoryException - * if the file could not otherwise be opened because it is not - * a directory (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the directory. - */ - public abstract DirectoryStream
newDirectoryStream(String glob) - throws IOException; - - /** - * Opens the directory referenced by this object, returning a {@code - * DirectoryStream} to iterate over the entries in the directory. The - * elements returned by the directory stream's {@link DirectoryStream#iterator - * iterator} are of type {@code Path}, each one representing an entry in the - * directory. The {@code Path} objects are obtained as if by {@link - * #resolve(Path) resolving} the name of the directory entry against this - * path. The entries returned by the iterator are filtered by the given - * {@link DirectoryStream.Filter filter}. - * - * The directory stream's {@code close} method should be invoked after - * iteration is completed so as to free any resources held for the open - * directory. - * - *
Where the filter terminates due to an uncaught error or runtime - * exception then it is propagated to the {@link Iterator#hasNext() - * hasNext} or {@link Iterator#next() next} method. Where an {@code - * IOException} is thrown, it results in the {@code hasNext} or {@code - * next} method throwing a {@link DirectoryIteratorException} with the - * {@code IOException} as the cause. - * - *
When an implementation supports operations on entries in the - * directory that execute in a race-free manner then the returned directory - * stream is a {@link SecureDirectoryStream}. - * - *
Usage Example: - * Suppose we want to iterate over the files in a directory that are - * larger than 8K. - *
- * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { - * public boolean accept(Path file) throws IOException { - * long size = Attributes.readBasicFileAttributes(file).size(); - * return (size > 8192L); - * } - * }; - * Path dir = ... - * DirectoryStream<Path> stream = dir.newDirectoryStream(filter); - *- * @param filter - * the directory stream filter - * - * @return a new and open {@code DirectoryStream} object - * - * @throws NotDirectoryException - * if the file could not otherwise be opened because it is not - * a directory (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the directory. - */ - public abstract DirectoryStreamnewDirectoryStream(DirectoryStream.Filter super Path> filter) - throws IOException; - - /** - * Creates a new and empty file, failing if the file already exists. - * - * This {@code Path} locates the file to create. The check for the - * existence of the file and the creation of the new file if it does not - * exist are a single operation that is atomic with respect to all other - * filesystem activities that might affect the directory. - * - *
The {@code attrs} parameter is an optional array of {@link FileAttribute - * file-attributes} to set atomically when creating the file. Each attribute - * is identified by its {@link FileAttribute#name name}. If more than one - * attribute of the same name is included in the array then all but the last - * occurrence is ignored. - * - * @param attrs - * an optional list of file attributes to set atomically when - * creating the file - * - * @return this path - * - * @throws UnsupportedOperationException - * if the array contains an attribute that cannot be set atomically - * when creating the file - * @throws FileAlreadyExistsException - * if a file of that name already exists - * (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked to check write access to the new file. - */ - public abstract Path createFile(FileAttribute>... attrs) throws IOException; + Path toRealPath(boolean resolveLinks) throws IOException; /** - * Creates a new directory. + * Returns a {@link File} object representing this path. Where this {@code + * Path} is associated with the default provider, then this method is + * equivalent to returning a {@code File} object constructed with the + * {@code String} representation of this path. * - *
This {@code Path} locates the directory to create. The check for the - * existence of the file and the creation of the directory if it does not - * exist are a single operation that is atomic with respect to all other - * filesystem activities that might affect the directory. + *
If this path was created by invoking the {@code File} {@link + * File#toPath toPath} method then there is no guarantee that the {@code + * File} object returned by this method is {@link #equals equal} to the + * original {@code File}. * - *
The {@code attrs} parameter is an optional array of {@link FileAttribute - * file-attributes} to set atomically when creating the directory. Each - * file attribute is identified by its {@link FileAttribute#name name}. If - * more than one attribute of the same name is included in the array then all - * but the last occurrence is ignored. - * - * @param attrs - * an optional list of file attributes to set atomically when - * creating the directory - * - * @return this path + * @return a {@code File} object representing this path * * @throws UnsupportedOperationException - * if the array contains an attribute that cannot be set atomically - * when creating the directory - * @throws FileAlreadyExistsException - * if a directory could not otherwise be created because a file of - * that name already exists (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked to check write access to the new directory. - * - * @see Files#createDirectories + * if this {@code Path} is not associated with the default provider */ - public abstract Path createDirectory(FileAttribute>... attrs) - throws IOException; - - /** - * Opens or creates a file, returning a seekable byte channel to access the - * file. - * - *
The {@code options} parameter determines how the file is opened. - * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE WRITE} - * options determine if the file should be opened for reading and/or writing. - * If neither option (or the {@link StandardOpenOption#APPEND APPEND} - * option) is contained in the array then the file is opened for reading. - * By default reading or writing commences at the beginning of the file. - * - *
In the addition to {@code READ} and {@code WRITE}, the following - * options may be present: - * - *
- *
- * - *- * Option Description - * - *{@link StandardOpenOption#APPEND APPEND} - *If this option is present then the file is opened for writing and - * each invocation of the channel's {@code write} method first advances - * the position to the end of the file and then writes the requested - * data. Whether the advancement of the position and the writing of the - * data are done in a single atomic operation is system-dependent and - * therefore unspecified. This option may not be used in conjunction - * with the {@code READ} or {@code TRUNCATE_EXISTING} options. - *- * - *{@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} - *If this option is present then the existing file is truncated to - * a size of 0 bytes. This option is ignored when the file is opened only - * for reading. - *- * - *{@link StandardOpenOption#CREATE_NEW CREATE_NEW} - *If this option is present then a new file is created, failing if - * the file already exists or is a symbolic link. When creating a file the - * check for the existence of the file and the creation of the file if it - * does not exist is atomic with respect to other file system operations. - * This option is ignored when the file is opened only for reading. - *- * - *{@link StandardOpenOption#CREATE CREATE} - *If this option is present then an existing file is opened if it - * exists, otherwise a new file is created. This option is ignored if the - * {@code CREATE_NEW} option is also present or the file is opened only - * for reading. - *- * - *{@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} - *When this option is present then the implementation makes a - * best effort attempt to delete the file when closed by the - * {@link SeekableByteChannel#close close} method. If the {@code close} - * method is not invoked then a best effort attempt is made to - * delete the file when the Java virtual machine terminates. - *- * - *{@link StandardOpenOption#SPARSE SPARSE} - *When creating a new file this option is a hint that the - * new file will be sparse. This option is ignored when not creating - * a new file. - *- * {@link StandardOpenOption#SYNC SYNC} - *Requires that every update to the file's content or metadata be - * written synchronously to the underlying storage device. (see Synchronized I/O file - * integrity). - *- * - * - *{@link StandardOpenOption#DSYNC DSYNC} - *Requires that every update to the file's content be written - * synchronously to the underlying storage device. (see Synchronized I/O file - * integrity). - *An implementation may also support additional implementation specific - * options. - * - *
The {@code attrs} parameter is an optional array of file {@link - * FileAttribute file-attributes} to set atomically when a new file is created. - * - *
In the case of the default provider, the returned seekable byte channel - * is a {@link java.nio.channels.FileChannel}. - * - *
Usage Examples: - *
- * Path file = ... - * - * // open file for reading - * ReadableByteChannel rbc = file.newByteChannel(EnumSet.of(READ))); - * - * // open file for writing to the end of an existing file, creating - * // the file if it doesn't already exist - * WritableByteChannel wbc = file.newByteChannel(EnumSet.of(CREATE,APPEND)); - * - * // create file with initial permissions, opening it for both reading and writing - * FileAttribute<Set<PosixFilePermission>> perms = ... - * SeekableByteChannel sbc = file.newByteChannel(EnumSet.of(CREATE_NEW,READ,WRITE), perms); - *- * - * @param options - * Options specifying how the file is opened - * @param attrs - * An optional list of file attributes to set atomically when - * creating the file - * - * @return a new seekable byte channel - * - * @throws IllegalArgumentException - * if the set contains an invalid combination of options - * @throws UnsupportedOperationException - * if an unsupported open option is specified or the array contains - * attributes that cannot be set atomically when creating the file - * @throws FileAlreadyExistsException - * if a file of that name already exists and the {@link - * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified - * (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the path if the file is - * opened for reading. The {@link SecurityManager#checkWrite(String) - * checkWrite} method is invoked to check write access to the path - * if the file is opened for writing. - */ - public abstract SeekableByteChannel newByteChannel(Set extends OpenOption> options, - FileAttribute>... attrs) - throws IOException; - - /** - * Opens or creates a file, returning a seekable byte channel to access the - * file. - * - *This method opens or creates a file in exactly the manner specified - * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel} - * method. - * - * @param options - * options specifying how the file is opened - * - * @return a new seekable byte channel - * - * @throws IllegalArgumentException - * if the set contains an invalid combination of options - * @throws UnsupportedOperationException - * if an unsupported open option is specified - * @throws FileAlreadyExistsException - * if a file of that name already exists and the {@link - * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified - * (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the path if the file is - * opened for reading. The {@link SecurityManager#checkWrite(String) - * checkWrite} method is invoked to check write access to the path - * if the file is opened for writing. - */ - public abstract SeekableByteChannel newByteChannel(OpenOption... options) - throws IOException; - - /** - * Opens or creates the file located by this object for writing, returning - * an output stream to write bytes to the file. - * - *
This method opens or creates a file in exactly the manner specified - * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel} - * method except that the {@link StandardOpenOption#READ READ} option may not - * be present in the array of open options. - * - * @param options - * options specifying how the file is opened - * - * @return a new output stream - * - * @throws IllegalArgumentException {@inheritDoc} - * @throws UnsupportedOperationException {@inheritDoc} - * @throws IOException {@inheritDoc} - * @throws SecurityException {@inheritDoc} - */ - @Override - public abstract OutputStream newOutputStream(OpenOption... options) - throws IOException; - - /** - * Tells whether or not the file located by this object is considered - * hidden. The exact definition of hidden is platform or provider - * dependent. On UNIX for example a file is considered to be hidden if its - * name begins with a period character ('.'). On Windows a file is - * considered hidden if it isn't a directory and the DOS {@link - * DosFileAttributes#isHidden hidden} attribute is set. - * - *
Depending on the implementation this method may require to access - * the file system to determine if the file is considered hidden. - * - * @return {@code true} if the file is considered hidden - * - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the file. - */ - public abstract boolean isHidden() throws IOException; - - /** - * Checks the existence and optionally the accessibility of the file - * located by this path. - * - *
This method checks the existence of a file and that this Java virtual - * machine has appropriate privileges that would allow it access the file - * according to all of access modes specified in the {@code modes} parameter - * as follows: - * - *
- *
- * - *- * Value Description - * - *{@link AccessMode#READ READ} - *Checks that the file exists and that the Java virtual machine has - * permission to read the file. - *- * - *{@link AccessMode#WRITE WRITE} - *Checks that the file exists and that the Java virtual machine has - * permission to write to the file, - *- * - *{@link AccessMode#EXECUTE EXECUTE} - *Checks that the file exists and that the Java virtual machine has - * permission to {@link Runtime#exec execute} the file. The semantics - * may differ when checking access to a directory. For example, on UNIX - * systems, checking for {@code EXECUTE} access checks that the Java - * virtual machine has permission to search the directory in order to - * access file or subdirectories. - *If the {@code modes} parameter is of length zero, then the existence - * of the file is checked. - * - *
This method follows symbolic links if the file referenced by this - * object is a symbolic link. Depending on the implementation, this method - * may require to read file permissions, access control lists, or other - * file attributes in order to check the effective access to the file. To - * determine the effective access to a file may require access to several - * attributes and so in some implementations this method may not be atomic - * with respect to other file system operations. Furthermore, as the result - * of this method is immediately outdated, there is no guarantee that a - * subsequence access will succeed (or even that it will access the same - * file). Care should be taken when using this method in security sensitive - * applications. - * - * @param modes - * The access modes to check; may have zero elements - * - * @throws UnsupportedOperationException - * an implementation is required to support checking for - * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This - * exception is specified to allow for the {@code Access} enum to - * be extended in future releases. - * @throws NoSuchFileException - * if a file does not exist (optional specific exception) - * @throws AccessDeniedException - * the requested access would be denied or the access cannot be - * determined because the Java virtual machine has insufficient - * privileges or other reasons. (optional specific exception) - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * is invoked when checking read access to the file or only the - * existence of the file, the {@link SecurityManager#checkWrite(String) - * checkWrite} is invoked when checking write access to the file, - * and {@link SecurityManager#checkExec(String) checkExec} is invoked - * when checking execute access. - */ - public abstract void checkAccess(AccessMode... modes) throws IOException; - - /** - * Tests whether the file located by this path exists. - * - *
This convenience method is intended for cases where it is required to - * take action when it can be confirmed that a file exists. This method simply - * invokes the {@link #checkAccess checkAccess} method to check if the file - * exists. If the {@code checkAccess} method succeeds then this method returns - * {@code true}, otherwise if an {@code IOException} is thrown (because the - * file doesn't exist or cannot be accessed by this Java virtual machine) - * then {@code false} is returned. - * - *
Note that the result of this method is immediately outdated. If this - * method indicates the file exists then there is no guarantee that a - * subsequence access will succeed. Care should be taken when using this - * method in security sensitive applications. - * - * @return {@code true} if the file exists; {@code false} if the file does - * not exist or its existence cannot be determined. - * - * @throws SecurityException - * In the case of the default provider, the {@link - * SecurityManager#checkRead(String)} is invoked to check - * read access to the file. - * - * @see #notExists - */ - public abstract boolean exists(); - - /** - * Tests whether the file located by this path does not exist. - * - *
This convenience method is intended for cases where it is required to - * take action when it can be confirmed that a file does not exist. This - * method invokes the {@link #checkAccess checkAccess} method to check if the - * file exists. If the file does not exist then {@code true} is returned, - * otherwise the file exists or cannot be accessed by this Java virtual - * machine and {@code false} is returned. - * - *
Note that this method is not the complement of the {@link #exists - * exists} method. Where it is not possible to determine if a file exists - * or not then both methods return {@code false}. As with the {@code exists} - * method, the result of this method is immediately outdated. If this - * method indicates the file does exist then there is no guarantee that a - * subsequence attempt to create the file will succeed. Care should be taken - * when using this method in security sensitive applications. - * - * @return {@code true} if the file does not exist; {@code false} if the - * file exists or its existence cannot be determined. - * - * @throws SecurityException - * In the case of the default provider, the {@link - * SecurityManager#checkRead(String)} is invoked to check - * read access to the file. - */ - public abstract boolean notExists(); - - /** - * Returns the {@link FileStore} representing the file store where an - * existing file, located by this path, is stored. - * - *
Once a reference to the {@code FileStore} is obtained it is - * implementation specific if operations on the returned {@code FileStore}, - * or {@link FileStoreAttributeView} objects obtained from it, continue - * to depend on the existence of the file. In particular the behavior is not - * defined for the case that the file is deleted or moved to a different - * file store. - * - * @return the file store where the file is stored - * - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to the file, and in - * addition it checks {@link RuntimePermission} - * ("getFileStoreAttributes") - */ - public abstract FileStore getFileStore() throws IOException; + File toFile(); // -- watchable -- @@ -1471,8 +594,8 @@ public abstract class Path * *
In this release, this path locates a directory that exists. The * directory is registered with the watch service so that entries in the - * directory can be watched. The {@code events} parameter is an array of - * events to register and may contain the following events: + * directory can be watched. The {@code events} parameter is the events to + * register and may contain the following events: *
*
- {@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} - * entry created or moved into the directory
@@ -1489,10 +612,10 @@ public abstract class Path *The set of events may include additional implementation specific * event that are not defined by the enum {@link StandardWatchEventKind} * - *
The {@code modifiers} parameter is an array of modifiers - * that qualify how the directory is registered. This release does not - * define any standard modifiers. The array may contain - * implementation specific modifiers. + *
The {@code modifiers} parameter specifies modifiers that + * qualify how the directory is registered. This release does not define any + * standard modifiers. It may contain implementation specific + * modifiers. * *
Where a file is registered with a watch service by means of a symbolic * link then it is implementation specific if the watch continues to depend @@ -1525,9 +648,9 @@ public abstract class Path * method is invoked to check read access to the file. */ @Override - public abstract WatchKey register(WatchService watcher, - WatchEvent.Kind>[] events, - WatchEvent.Modifier... modifiers) + WatchKey register(WatchService watcher, + WatchEvent.Kind>[] events, + WatchEvent.Modifier... modifiers) throws IOException; /** @@ -1573,8 +696,8 @@ public abstract class Path * method is invoked to check read access to the file. */ @Override - public abstract WatchKey register(WatchService watcher, - WatchEvent.Kind>... events) + WatchKey register(WatchService watcher, + WatchEvent.Kind>... events) throws IOException; // -- Iterable -- @@ -1591,7 +714,7 @@ public abstract class Path * @return an iterator over the name elements of this path. */ @Override - public abstract Iterator
iterator(); + Iterator iterator(); // -- compareTo/equals/hashCode -- @@ -1609,50 +732,7 @@ public abstract class Path * lexicographically greater than the argument */ @Override - public abstract int compareTo(Path other); - - /** - * Tests if the file referenced by this object is the same file referenced - * by another object. - * - * If this {@code Path} and the given {@code Path} are {@link - * #equals(Object) equal} then this method returns {@code true} without checking - * if the file exists. If the {@code Path} and the given {@code Path} - * are associated with different providers, or the given {@code Path} is - * {@code null} then this method returns {@code false}. Otherwise, this method - * checks if both {@code Paths} locate the same file, and depending on the - * implementation, may require to open or access both files. - * - *
If the file system and files remain static, then this method implements - * an equivalence relation for non-null {@code Paths}. - *
- *
- * - * @param other - * the other file reference - * - * @return {@code true} if, and only if, this object and the given object - * locate the same file - * - * @throws IOException - * if an I/O error occurs - * @throws SecurityException - * In the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkRead(String) checkRead} - * method is invoked to check read access to both files. - * - * @see java.nio.file.attribute.BasicFileAttributes#fileKey - */ - public abstract boolean isSameFile(Path other) throws IOException; + int compareTo(Path other); /** * Tests this path for equality with the given object. @@ -1663,7 +743,9 @@ public abstract class Path *- It is reflexive: for a non-null {@code Path} {@code f}, - * {@code f.isSameFile(f)} should return {@code true}. - *
- It is symmetric: for two non-null {@code Path} - * {@code f} and {@code g}, {@code f.isSameFile(g)} will equal - * {@code g.isSameFile(f)}. - *
- It is transitive: for three {@code Paths} - * {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns - * {@code true} and {@code g.isSameFile(h)} returns {@code true}, then - * {@code f.isSameFile(h)} will return return {@code true}. - *
Whether or not two path are equal depends on the file system * implementation. In some cases the paths are compared without regard * to case, and others are case sensitive. This method does not access the - * file system and the file is not required to exist. + * file system and the file is not required to exist. Where required, the + * {@link Files#isSameFile isSameFile} method may be used to check if two + * paths locate the same file. * *
This method satisfies the general contract of the {@link * java.lang.Object#equals(Object) Object.equals} method.
@@ -1674,8 +756,7 @@ public abstract class Path * @return {@code true} if, and only if, the given object is a {@code Path} * that is identical to this {@code Path} */ - @Override - public abstract boolean equals(Object other); + boolean equals(Object other); /** * Computes a hash code for this path. @@ -1686,8 +767,7 @@ public abstract class Path * * @return the hash-code value for this path */ - @Override - public abstract int hashCode(); + int hashCode(); /** * Returns the string representation of this path. @@ -1701,6 +781,5 @@ public abstract class Path * * @return the string representation of this path */ - @Override - public abstract String toString(); + String toString(); } diff --git a/src/share/classes/java/nio/file/PathMatcher.java b/src/share/classes/java/nio/file/PathMatcher.java index 39af77d6b06522ce2305208db62fa674399dc005..952f18f17f9b820ef9edb4549898dc20e4ddd650 100644 --- a/src/share/classes/java/nio/file/PathMatcher.java +++ b/src/share/classes/java/nio/file/PathMatcher.java @@ -32,7 +32,7 @@ package java.nio.file; * @since 1.7 * * @see FileSystem#getPathMatcher - * @see Path#newDirectoryStream(String) + * @see Files#newDirectoryStream(Path,String) */ public interface PathMatcher { diff --git a/src/share/classes/java/nio/file/Paths.java b/src/share/classes/java/nio/file/Paths.java index be51761c486eb5102e78d58fa5d92ff1009e8fcb..d0906d4443f5f7f89ae01856ce418abaff73ddb4 100644 --- a/src/share/classes/java/nio/file/Paths.java +++ b/src/share/classes/java/nio/file/Paths.java @@ -39,14 +39,27 @@ public final class Paths { private Paths() { } /** - * Constructs a {@code Path} by converting the given path string. + * Converts a path string, or a sequence of strings that when joined form + * a path string, to a {@code Path}. If {@code more} does not specify any + * elements then the value of the {@code first} parameter is the path string + * to convert. If {@code more} specifies one or more elements then each + * non-empty string, including {@code first}, is considered to be a sequence + * of name elements (see {@link Path}) and is joined to form a path string. + * The details as to how the Strings are joined is provider specific but + * typically they will be joined using the {@link FileSystem#getSeparator + * name-separator} as the separator. For example, if the name separator is + * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the + * path string {@code "/foo/bar/gus"} is converted to a {@code Path}. + * A {@code Path} representing an empty path is returned if {@code first} + * is the empty string and {@code more} does not contain any non-empty + * strings. * *The {@code Path} is obtained by invoking the {@link FileSystem#getPath * getPath} method of the {@link FileSystems#getDefault default} {@link * FileSystem}. * - *
Note that while this method is very convenient, using it will - * imply an assumed reference to the default FileSystem and limit the + *
Note that while this method is very convenient, using it will imply + * an assumed reference to the default {@code FileSystem} and limit the * utility of the calling code. Hence it should not be used in library code * intended for flexible reuse. A more flexible alternative is to use an * existing {@code Path} instance as an anchor, such as: @@ -55,8 +68,10 @@ public final class Paths { * Path path = dir.resolve("file"); *
A {@code SecureDirectoryStream} requires corresponding support from the
* underlying operating system. Where an implementation supports this features
- * then the {@code DirectoryStream} returned by the {@link Path#newDirectoryStream
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
* newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
* be cast to that type in order to invoke the methods defined by this interface.
*
@@ -56,20 +56,15 @@ import java.io.IOException;
* @since 1.7
*/
-public abstract class SecureDirectoryStream This method works in exactly the manner specified by the {@link
- * Path#newDirectoryStream() newDirectoryStream} method for the case that
+ * Files#newDirectoryStream(Path) newDirectoryStream} method for the case that
* the {@code path} parameter is an {@link Path#isAbsolute absolute} path.
* When the parameter is a relative path then the directory to open is
* relative to this open directory. The {@link
@@ -99,8 +94,7 @@ public abstract class SecureDirectoryStream This method works in exactly the manner specified by the {@link
- * Path#newByteChannel Path.newByteChannel} method for the
+ * Files#newByteChannel Files.newByteChannel} method for the
* case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
* path. When the parameter is a relative path then the file to open or
* create is relative to this open directory. In addition to the options
- * defined by the {@code Path.newByteChannel} method, the {@link
+ * defined by the {@code Files.newByteChannel} method, the {@link
* LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
* ensure that this method fails if the file is a symbolic link.
*
@@ -149,15 +143,15 @@ public abstract class SecureDirectoryStream Unlike the {@link Path#delete delete()} method, this method does
+ * Unlike the {@link Files#delete delete()} method, this method does
* not first examine the file to determine if the file is a directory.
* Whether a directory is deleted by this method is system dependent and
* therefore not specified. If the file is a symbolic link, then the link
@@ -179,12 +173,12 @@ public abstract class SecureDirectoryStream Unlike the {@link Path#delete delete()} method, this method
+ * Unlike the {@link Files#delete delete()} method, this method
* does not first examine the file to determine if the file is a directory.
* Whether non-directories are deleted by this method is system dependent and
* therefore not specified. When the parameter is a relative path then the
@@ -207,12 +201,12 @@ public abstract class SecureDirectoryStream This method works in a similar manner to {@link Path#moveTo moveTo}
+ * This method works in a similar manner to {@link Files#move move}
* method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
* is specified. That is, this method moves a file as an atomic file system
* operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
@@ -247,7 +241,7 @@ public abstract class SecureDirectoryStream If this watch key has already been cancelled then invoking this
* method has no effect. Once cancelled, a watch key remains forever invalid.
*/
- public abstract void cancel();
+ void cancel();
+
+ /**
+ * Returns the object for which this watch key was created. This method will
+ * continue to return the object even after the key is cancelled.
+ *
+ * As the {@code WatchService} is intended to map directly on to the
+ * native file event notification facility (where available) then many of
+ * details on how registered objects are watched is highly implementation
+ * specific. When watching a directory for changes for example, and the
+ * directory is moved or renamed in the file system, there is no guarantee
+ * that the watch key will be cancelled and so the object returned by this
+ * method may no longer be a valid path to the directory.
+ *
+ * @return the object for which this watch key was created
+ */
+ //T watchable();
}
diff --git a/src/share/classes/java/nio/file/WatchService.java b/src/share/classes/java/nio/file/WatchService.java
index 048472b6cdb0fdd650e88b1504cf8345686edb0e..255e03fe51880b1e13edefaca98796d8371c6588 100644
--- a/src/share/classes/java/nio/file/WatchService.java
+++ b/src/share/classes/java/nio/file/WatchService.java
@@ -103,13 +103,9 @@ import java.util.concurrent.TimeUnit;
* @see FileSystem#newWatchService
*/
-public abstract class WatchService
- implements Closeable
+public interface WatchService
+ extends Closeable
{
- /**
- * Initializes a new instance of this class.
- */
- protected WatchService() { }
/**
* Closes this watch service.
@@ -129,7 +125,7 @@ public abstract class WatchService
* if an I/O error occurs
*/
@Override
- public abstract void close() throws IOException;
+ void close() throws IOException;
/**
* Retrieves and removes the next watch key, or {@code null} if none are
@@ -140,7 +136,7 @@ public abstract class WatchService
* @throws ClosedWatchServiceException
* if this watch service is closed
*/
- public abstract WatchKey poll();
+ WatchKey poll();
/**
* Retrieves and removes the next watch key, waiting if necessary up to the
@@ -160,7 +156,7 @@ public abstract class WatchService
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey poll(long timeout, TimeUnit unit)
+ WatchKey poll(long timeout, TimeUnit unit)
throws InterruptedException;
/**
@@ -174,5 +170,5 @@ public abstract class WatchService
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey take() throws InterruptedException;
+ WatchKey take() throws InterruptedException;
}
diff --git a/src/share/classes/java/nio/file/attribute/AclEntry.java b/src/share/classes/java/nio/file/attribute/AclEntry.java
index b49944c1894c65d969998045c4b145e71cb9efdc..a0ea1fd16d5f5369c9b0d9109c562bd7c570f2cd 100644
--- a/src/share/classes/java/nio/file/attribute/AclEntry.java
+++ b/src/share/classes/java/nio/file/attribute/AclEntry.java
@@ -176,7 +176,7 @@ public final class AclEntry {
*/
public Builder setPermissions(Set Usage Example:
* Suppose we wish to add an entry to an existing ACL to grant "joe" access:
@@ -75,7 +75,7 @@ import java.io.IOException;
* .lookupPrincipalByName("joe");
*
* // get view
- * AclFileAttributeView view = file.getFileAttributeView(AclFileAttributeView.class);
+ * AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
*
* // create ACE to give "joe" read access
* AclEntry entry = AclEntry.newBuilder()
@@ -110,11 +110,11 @@ import java.io.IOException;
*
*
*
- * The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * The {@link Files#getAttribute getAttribute} method may be used to read
* the ACL or owner attributes as if by invoking the {@link #getAcl getAcl} or
* {@link #getOwner getOwner} methods.
*
- * The {@link FileRef#setAttribute setAttribute} method may be used to
+ * The {@link Files#setAttribute setAttribute} method may be used to
* update the ACL or owner attributes as if by invoking the {@link #setAcl setAcl}
* or {@link #setOwner setOwner} methods.
*
@@ -122,8 +122,8 @@ import java.io.IOException;
*
* Implementations supporting this attribute view may also support setting
* the initial ACL when creating a file or directory. The initial ACL
- * may be provided to methods such as {@link Path#createFile createFile} or {@link
- * Path#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
* FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
* value} that is the list of {@code AclEntry} objects.
*
@@ -135,8 +135,6 @@ import java.io.IOException;
* translation.
*
* @since 1.7
- * @see Attributes#getAcl
- * @see Attributes#setAcl
*/
public interface AclFileAttributeView
diff --git a/src/share/classes/java/nio/file/attribute/Attributes.java b/src/share/classes/java/nio/file/attribute/Attributes.java
deleted file mode 100644
index 32dbec38ee602a63518a82debe409a78f123f67b..0000000000000000000000000000000000000000
--- a/src/share/classes/java/nio/file/attribute/Attributes.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * the attributes of files or file stores. These methods provide for convenient
- * use of the {@link AttributeView attribute-views} defined in this package.
- *
- * @since 1.7
- */
-
-public final class Attributes {
- private Attributes() { }
-
- /**
- * Reads the basic file attributes of a file.
- *
- * The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- * This option should be used where there is a need to determine if a
- * file is a symbolic link:
- * It is implementation specific if all file attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The basic file attributes
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see BasicFileAttributeView#readAttributes
- */
- public static BasicFileAttributes readBasicFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- return file.getFileAttributeView(BasicFileAttributeView.class, options)
- .readAttributes();
- }
-
- /**
- * Reads the POSIX file attributes of a file.
- *
- * The {@code file} parameter locates a file that supports the {@link
- * PosixFileAttributeView}. This file attribute view provides access to a
- * subset of the file attributes commonly associated with files on file
- * systems used by operating systems that implement the Portable Operating
- * System Interface (POSIX) family of standards. It is implementation
- * specific if all file attributes are read as an atomic operation with
- * respect to other file system operations.
- *
- * The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The POSIX file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code PosixFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see PosixFileAttributeView#readAttributes
- */
- public static PosixFileAttributes readPosixFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Reads the DOS file attributes of a file.
- *
- * The {@code file} parameter locates a file that supports the {@link
- * DosFileAttributeView}. This file attribute view provides access to
- * legacy "DOS" attributes supported by the file systems such as File
- * Allocation Table (FAT), commonly used in consumer devices. It is
- * implementation specific if all file attributes are read as an atomic
- * operation with respect to other file system operations.
- *
- * The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The DOS file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code DosFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see DosFileAttributeView#readAttributes
- */
- public static DosFileAttributes readDosFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- DosFileAttributeView view =
- file.getFileAttributeView(DosFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Returns the owner of a file.
- *
- * The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return A user principal representing the owner of the file
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see FileOwnerAttributeView#getOwner
- */
- public static UserPrincipal getOwner(FileRef file) throws IOException {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.getOwner();
- }
-
- /**
- * Updates the file owner.
- *
- * The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- * @param owner
- * The new file owner
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see FileOwnerAttributeView#setOwner
- */
- public static void setOwner(FileRef file, UserPrincipal owner)
- throws IOException
- {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setOwner(owner);
- }
-
- /**
- * Reads a file's Access Control List (ACL).
- *
- * The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * RFC 3530.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return An ordered list of {@link AclEntry entries} representing the
- * ACL. The returned list is modifiable.
- *
- * @throws UnsupportedOperationException
- * If the {@code AclAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see AclFileAttributeView#getAcl
- */
- public static List The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * RFC 3530.
- *
- * @param file
- * A file reference that locates the file
- * @param acl
- * The new file ACL
- *
- * @throws UnsupportedOperationException
- * If the {@code AclFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see AclFileAttributeView#setAcl
- */
- public static void setAcl(FileRef file, List If the file system does not support a last modified time attribute
- * then this method has no effect.
- *
- * Usage Example:
- * Suppose we want to set the last modified time to the current time:
- * If the file system does not support a last access time attribute then
- * this method has no effect.
- *
- * @param file
- * A file reference that locates the file
- * @param lastAccessTime
- * The new last access time
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastAccessTime(FileRef file,
- FileTime lastAccessTime)
- throws IOException
- {
- if (lastAccessTime == null)
- throw new NullPointerException("'lastAccessTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(null, lastAccessTime, null);
- }
-
- /**
- * Sets a file's POSIX permissions.
- *
- * The {@code file} parameter is a reference to an existing file. It
- * supports the {@link PosixFileAttributeView} that provides access to file
- * attributes commonly associated with files on file systems used by
- * operating systems that implement the Portable Operating System Interface
- * (POSIX) family of standards.
- *
- * @param file
- * A file reference that locates the file
- * @param perms
- * The new set of permissions
- *
- * @throws UnsupportedOperationException
- * If {@code PosixFileAttributeView} is not available
- * @throws ClassCastException
- * If the sets contains elements that are not of type {@code
- * PosixFilePermission}
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}("accessUserInformation")
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see PosixFileAttributeView#setPermissions
- */
- public static void setPosixFilePermissions(FileRef file,
- Set The {@code store} parameter is a file store that supports the
- * {@link FileStoreSpaceAttributeView} providing access to the space related
- * attributes of the file store. It is implementation specific if all attributes
- * are read as an atomic operation with respect to other file system operations.
- *
- * @param store
- * The file store
- *
- * @return The file store space attributes
- *
- * @throws UnsupportedOperationException
- * If the file store space attribute view is not supported
- * @throws IOException
- * If an I/O error occurs
- *
- * @see FileStoreSpaceAttributeView#readAttributes()
- */
- public static FileStoreSpaceAttributes readFileStoreSpaceAttributes(FileStore store)
- throws IOException
- {
- FileStoreSpaceAttributeView view =
- store.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-}
diff --git a/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java b/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
index e2534812e99c2b54b97a00b95bffb4c7e208c924..4c50f82e9526f705099553272d2eb32330453797 100644
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
@@ -85,16 +85,15 @@ import java.io.IOException;
*
*
*
- * The {@link java.nio.file.FileRef#getAttribute getAttribute} method may be
+ * The {@link java.nio.file.Files#getAttribute getAttribute} method may be
* used to read any of these attributes as if by invoking the {@link
* #readAttributes() readAttributes()} method.
*
- * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be
* used to update the file's last modified time, last access time or create time
* attributes as if by invoking the {@link #setTimes setTimes} method.
*
* @since 1.7
- * @see Attributes
*/
public interface BasicFileAttributeView
@@ -131,9 +130,10 @@ public interface BasicFileAttributeView
* This method updates the file's timestamp attributes. The values are
* converted to the epoch and precision supported by the file system.
* Converting from finer to coarser granularities result in precision loss.
- * The behavior of this method when attempting to set a timestamp to a value
- * that is outside the range supported by the underlying file store is not
- * defined. It may or not fail by throwing an {@code IOException}.
+ * The behavior of this method when attempting to set a timestamp that is
+ * not supported or to a value that is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
*
* If any of the {@code lastModifiedTime}, {@code lastAccessTime},
* or {@code createTime} parameters has the value {@code null} then the
@@ -146,6 +146,14 @@ public interface BasicFileAttributeView
* lastAccessTime} and {@code createTime} parameters are {@code null} then
* this method has no effect.
*
+ * Usage Example:
+ * Suppose we want to change a file's creation time.
+ * Usage Example:
* If the file system implementation does not support a time stamp
+ * to indicate the time of last modification then this method returns an
+ * implementation specific default value, typically a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
* @return a {@code FileTime} representing the time the file was last
- * modified or {@code null} if the attribute is not supported.
+ * modified
*/
FileTime lastModifiedTime();
/**
- * Returns the time of last access if supported.
+ * Returns the time of last access.
+ *
+ * If the file system implementation does not support a time stamp
+ * to indicate the time of last access then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
*
- * @return a {@code FileTime} representing the time of last access or
- * {@code null} if the attribute is not supported.
+ * @return a {@code FileTime} representing the time of last access
*/
FileTime lastAccessTime();
/**
- * Returns the creation time if supported. The creation time is the time
- * that the file was created.
+ * Returns the creation time. The creation time is the time that the file
+ * was created.
+ *
+ * If the file system implementation does not support a time stamp
+ * to indicate the time when the file was created then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
*
- * @return a {@code FileTime} representing the time the file was created
- * or {@code null} if the attribute is not supported.
+ * @return a {@code FileTime} representing the time the file was created
*/
FileTime creationTime();
@@ -120,7 +135,7 @@ public interface BasicFileAttributes {
*
* File keys returned by this method can be compared for equality and are
* suitable for use in collections. If the file system and files remain static,
- * and two files are the {@link java.nio.file.Path#isSameFile same} with
+ * and two files are the {@link java.nio.file.Files#isSameFile same} with
* non-{@code null} file keys, then their file keys are equal.
*
* @see java.nio.file.Files#walkFileTree
diff --git a/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java b/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
index def09013e78dd30bb40d824c183fe74564da331c..7a21bae5fec8124d643bf69b4ff4b28cf56b870e 100644
--- a/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
+++ b/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
@@ -65,12 +65,12 @@ import java.io.IOException;
*
*
*
- * The {@link java.nio.file.FileRef#getAttribute getAttribute} method may
+ * The {@link java.nio.file.Files#getAttribute getAttribute} method may
* be used to read any of these attributes, or any of the attributes defined by
* {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
* readAttributes()} method.
*
- * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may
* be used to update the file's last modified time, last access time or create
* time attributes as defined by {@link BasicFileAttributeView}. It may also be
* used to update the DOS attributes as if by invoking the {@link #setReadOnly
diff --git a/src/share/classes/java/nio/file/attribute/DosFileAttributes.java b/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
index d8d22174e84b574b4acfc08b5ff3ae59e8555d19..d095d213358b3179b269fd88bb18688a03d4ffe0 100644
--- a/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
+++ b/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
@@ -29,13 +29,13 @@ package java.nio.file.attribute;
* File attributes associated with a file in a file system that supports
* legacy "DOS" attributes.
*
- * The DOS attributes of a file are retrieved using a {@link
- * DosFileAttributeView} by invoking its {@link DosFileAttributeView#readAttributes
- * readAttributes} method.
+ * Usage Example:
+ * The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
* be used to read or update the owner of the file.
*
- * The {@link java.nio.file.FileRef#getAttribute getAttribute} and
- * {@link java.nio.file.FileRef#setAttribute setAttribute} methods may also be
+ * The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#setAttribute setAttribute} methods may also be
* used to read or update the owner. In that case, the owner attribute is
* identified by the name {@code "owner"}, and the value of the attribute is
* a {@link UserPrincipal}.
diff --git a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java b/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java
deleted file mode 100644
index dca8d4f010c1690ed48e9ef2f34dce88269f0407..0000000000000000000000000000000000000000
--- a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.io.IOException;
-
-/**
- * A file store attribute view that supports reading of space attributes.
- *
- * Where dynamic access to file attributes is required, the attributes
- * supported by this attribute view have the following names and types:
- * The {@link java.nio.file.FileStore#getAttribute getAttribute} method may
- * be used to read any of these attributes.
- *
- * @since 1.7
- */
-
-public interface FileStoreSpaceAttributeView
- extends FileStoreAttributeView
-{
- /**
- * Returns the name of the attribute view. Attribute views of this type
- * have the name {@code "space"}.
- */
- @Override
- String name();
-
- /**
- * Reads the disk space attributes as a bulk operation.
- *
- * It is file system specific if all attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @return The disk space attributes
- *
- * @throws IOException
- * If an I/O error occurs
- */
- FileStoreSpaceAttributes readAttributes() throws IOException;
-}
diff --git a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java b/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java
deleted file mode 100644
index ff2bfb66f61f9acfb495dd820151b2c2b8f07da9..0000000000000000000000000000000000000000
--- a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-/**
- * Space related attributes of a file store.
- *
- * @since 1.7
- *
- * @see Attributes#readFileStoreSpaceAttributes
- */
-
-public interface FileStoreSpaceAttributes {
- /**
- * Returns the size, in bytes, of the file store.
- */
- long totalSpace();
-
- /**
- * Returns the number of bytes available to this Java virtual machine on the
- * file store.
- *
- * The returned number of available bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of usable bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be made inaccurate
- * by any external I/O operations including those made on the system outside
- * of this Java virtual machine.
- */
- long usableSpace();
-
- /**
- * Returns the number of unallocated bytes in the file store.
- *
- * The returned number of unallocated bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of unallocated bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be
- * made inaccurate by any external I/O operations including those made on
- * the system outside of this virtual machine.
- */
- long unallocatedSpace();
-}
diff --git a/src/share/classes/java/nio/file/attribute/FileTime.java b/src/share/classes/java/nio/file/attribute/FileTime.java
index 1b3d2ff2f84014cd2fcca2e888de52a563c4fb15..6cac437cdcef92b42732c6ae8bbf3bfe026a50e0 100644
--- a/src/share/classes/java/nio/file/attribute/FileTime.java
+++ b/src/share/classes/java/nio/file/attribute/FileTime.java
@@ -35,20 +35,53 @@ import java.util.concurrent.TimeUnit;
/**
* Represents the value of a file's time stamp attribute. For example, it may
- * represent the time that the file was last modified, accessed, or created.
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
*
* Instances of this class are immutable.
*
* @since 1.7
- * @see BasicFileAttributes
- * @see Attributes#setLastModifiedTime
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
*/
-public final class FileTime implements Comparable Usage Example:
* Suppose we need to print out the owner and access permissions of a file:
* The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * The {@link Files#getAttribute getAttribute} method may be used to read
* any of these attributes, or any of the attributes defined by {@link
* BasicFileAttributeView} as if by invoking the {@link #readAttributes
* readAttributes()} method.
*
- * The {@link FileRef#setAttribute setAttribute} method may be used to update
+ * The {@link Files#setAttribute setAttribute} method may be used to update
* the file's last modified time, last access time or create time attributes as
* defined by {@link BasicFileAttributeView}. It may also be used to update
* the permissions, owner, or group-owner as if by invoking the {@link
@@ -105,8 +105,8 @@ import java.io.IOException;
* Implementations supporting this attribute view may also support setting
* the initial permissions when creating a file or directory. The
- * initial permissions are provided to the {@link Path#createFile createFile}
- * or {@link Path#createDirectory createDirectory} methods as a {@link
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
* FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
* and a {@link FileAttribute#value value} that is the set of permissions. The
* following example uses the {@link PosixFilePermissions#asFileAttribute
@@ -117,7 +117,7 @@ import java.io.IOException;
* Path path = ...
* Set<PosixFilePermission> perms =
* EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
- * path.createFile(PosixFilePermissions.asFileAttribute(perms));
+ * Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
* When the access permissions are set at file creation time then the actual
@@ -128,13 +128,11 @@ import java.io.IOException;
* the access permissions, and the underlying file system supports access
* permissions, then it is required that the value of the actual access
* permissions will be equal or less than the value of the attribute
- * provided to the {@link java.nio.file.Path#createFile createFile} or
- * {@link java.nio.file.Path#createDirectory createDirectory} methods. In
- * other words, the file may be more secure than requested.
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributeView
diff --git a/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java b/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
index 6dfd650c327a06144e6c5c1108e26c990c48abe7..361d4c2cc6ebdc46397731e8445fe9c0d88150e7 100644
--- a/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
+++ b/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
@@ -37,8 +37,6 @@ import java.util.Set;
* PosixFileAttributeView#readAttributes readAttributes} method.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributes
diff --git a/src/share/classes/java/nio/file/attribute/PosixFilePermission.java b/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
index 3c5f33f86c77a86a450d308067b7c718225693ff..52419b7b0aa5edadabe9e4db47f5c81e6cfde032 100644
--- a/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
+++ b/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
@@ -25,14 +25,12 @@
package java.nio.file.attribute;
-import java.util.*;
-
/**
* Defines the bits for use with the {@link PosixFileAttributes#permissions()
* permissions} attribute.
*
- * The {@link PosixFileAttributes} class defines method methods for
- * manipulating {@link Set sets} of permissions.
+ * The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
*
* @since 1.7
*/
diff --git a/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java b/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
index b3903957ef3f02dba1e08e45635e7d08b005c853..7499fa9498feed5a78c4a32d4e4a90fd4ecbb824 100644
--- a/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
+++ b/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
@@ -126,7 +126,7 @@ public final class PosixFilePermissions {
public static Set Where dynamic access to file attributes is required, the {@link
- * java.nio.file.FileRef#getAttribute getAttribute} method may be used to read
+ * java.nio.file.Files#getAttribute getAttribute} method may be used to read
* the attribute value. The attribute value is returned as a byte array (byte[]).
- * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be used
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be used
* to write the value of a user-defined attribute from a buffer (as if by
* invoking the {@link #write write} method), or byte array (byte[]).
*
@@ -132,8 +132,8 @@ public interface UserDefinedFileAttributeView
* Suppose we want to read a file's MIME type that is stored as a user-defined
* attribute with the name "{@code user.mimetype}".
* Usage Example:
* Suppose we want to write a file's MIME type as a user-defined attribute:
* An attribute view provides a read-only or updatable view of the non-opaque
@@ -55,7 +53,7 @@
* The {@link java.nio.file.attribute.FileAttributeView} interface is
* extended by several other interfaces that that views to specific sets of file
* attributes. {@code FileAttributeViews} are selected by invoking the {@link
- * java.nio.file.FileRef#getFileAttributeView} method with a
+ * java.nio.file.Files#getFileAttributeView} method with a
* type-token to identify the required view. Views can also be identified
* by name. The {@link java.nio.file.attribute.FileStoreAttributeView} interface
* provides access to file store attributes. A {@code FileStoreAttributeView} of
@@ -83,13 +81,6 @@
* on the model defined by
* RFC 3530: Network File System (NFS) version 4 Protocol.
*
- * The {@link java.nio.file.attribute.FileStoreSpaceAttributeView} class
- * defines methods to read file system space usage related attributes of a file system.
- *
- * The {@link java.nio.file.attribute.Attributes} utility class defines
- * static methods to access file or file system attribute using the above
- * attribute views.
- *
* In addition to attribute views, this package also defines classes and
* interfaces that are used when accessing attributes:
*
diff --git a/src/share/classes/java/nio/file/package-info.java b/src/share/classes/java/nio/file/package-info.java
index d5fa4d6bbd72dc9641457c181a856b11cd073151..5a687774aef28b90f2fe7f63bdf8e0002a7e9078 100644
--- a/src/share/classes/java/nio/file/package-info.java
+++ b/src/share/classes/java/nio/file/package-info.java
@@ -31,7 +31,7 @@
* systems. The API to access file and file system attributes is defined in the
* {@link java.nio.file.attribute} package. The {@link java.nio.file.spi}
* package is used by service provider implementors wishing to extend the
- * platform default provider, or to construct other provider implementations.
+ * platform default provider, or to construct other provider implementations. Unless otherwise noted, methods that attempt to access the file system
* will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
@@ -95,12 +95,13 @@
* {@link java.nio.file.FileSystem#close closed}. Additionally, any methods
* that attempt write access to a file system will throw {@link
* java.nio.file.ReadOnlyFileSystemException} when invoked on an object associated
- * with a {@link java.nio.file.FileSystem} that only provides read-only access.
+ * with a {@link java.nio.file.FileSystem} that only provides read-only
+ * access. Unless otherwise noted, invoking a method of any class or interface in
* this package created by one {@link java.nio.file.spi.FileSystemProvider
* provider} with a parameter that is an object created by another provider,
- * will throw {@link java.nio.file.ProviderMismatchException}.
+ * will throw {@link java.nio.file.ProviderMismatchException}. A file system provider is a concrete implementation of this class that
* implements the abstract methods defined by this class. A provider is
@@ -64,13 +68,6 @@ import java.io.IOException;
* the {@code newFileSystem} method is invoked. In the case of the default
* provider, the {@code FileSystem} is created when the provider is initialized.
*
- * In addition to file systems, a provider is also a factory for {@link
- * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
- * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
- * AsynchronousFileChannel} methods are defined to open or create files, returning
- * a channel to access the file. These methods are invoked by static factory
- * methods defined in the {@link java.nio.channels} package.
- *
* All of the methods in this class are safe for use by multiple concurrent
* threads.
*
@@ -202,9 +199,10 @@ public abstract class FileSystemProvider {
*
* This method throws {@link FileSystemAlreadyExistsException} if the
* file system already exists because it was previously created by an
- * invocation of this method. Once a file system is {@link FileSystem#close
- * closed} it is provider-dependent if the provider allows a new file system
- * to be created with the same URI as a file system it previously created.
+ * invocation of this method. Once a file system is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+ * provider allows a new file system to be created with the same URI as a
+ * file system it previously created.
*
* @param uri
* URI reference
@@ -234,20 +232,21 @@ public abstract class FileSystemProvider {
*
* This method returns a reference to a {@code FileSystem} that was
* created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
- * method. File systems created the {@link #newFileSystem(FileRef,Map)
- * newFileSystem(FileRef,Map)} method are not returned by this method.
+ * method. File systems created the {@link #newFileSystem(Path,Map)
+ * newFileSystem(Path,Map)} method are not returned by this method.
* The file system is identified by its {@code URI}. Its exact form
* is highly provider dependent. In the case of the default provider the URI's
* path component is {@code "/"} and the authority, query and fragment components
* are undefined (Undefined components are represented by {@code null}).
*
- * Once a file system created by this provider is {@link FileSystem#close
- * closed} it is provider-dependent if this method returns a reference to
- * the closed file system or throws {@link FileSystemNotFoundException}.
- * If the provider allows a new file system to be created with the same URI
- * as a file system it previously created then this method throws the
- * exception if invoked after the file system is closed (and before a new
- * instance is created by the {@link #newFileSystem newFileSystem} method).
+ * Once a file system created by this provider is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+ * method returns a reference to the closed file system or throws {@link
+ * FileSystemNotFoundException}. If the provider allows a new file system to
+ * be created with the same URI as a file system it previously created then
+ * this method throws the exception if invoked after the file system is
+ * closed (and before a new instance is created by the {@link #newFileSystem
+ * newFileSystem} method).
*
* If a security manager is installed then a provider implementation
* may require to check a permission before returning a reference to an
@@ -306,17 +305,16 @@ public abstract class FileSystemProvider {
*
* This method is intended for specialized providers of pseudo file
* systems where the contents of one or more files is treated as a file
- * system. The {@code file} parameter is a reference to an existing file
- * and the {@code env} parameter is a map of provider specific properties to
- * configure the file system.
+ * system. The {@code env} parameter is a map of provider specific properties
+ * to configure the file system.
*
* If this provider does not support the creation of such file systems
* or if the provider does not recognize the file type of the given file then
* it throws {@code UnsupportedOperationException}. The default implementation
* of this method throws {@code UnsupportedOperationException}.
*
- * @param file
- * The file
+ * @param path
+ * The path to the file
* @param env
* A map of provider specific properties to configure the file system;
* may be empty
@@ -336,32 +334,121 @@ public abstract class FileSystemProvider {
* If a security manager is installed and it denies an unspecified
* permission.
*/
- public FileSystem newFileSystem(FileRef file, Map The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that reads bytes from the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
+ *
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt: options) {
+ if (opt != StandardOpenOption.READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return Channels.newInputStream(Files.newByteChannel(path));
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. This method works in exactly the manner
+ * specified by the {@link Files#newOutputStream} method.
*
- * This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
- * FileChannel.open} method to open a file channel. A provider that does not
- * support all the features required to construct a file channel throws
- * {@code UnsupportedOperationException}. The default provider is required
- * to support the creation of file channels. When not overridden, the
- * default implementation throws {@code UnsupportedOperationException}.
+ * The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that writes bytes to the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ int len = options.length;
+ Set This method is invoked by the {@link
+ * asynchronous file channel to access the file. This method works in
+ * exactly the manner specified by the {@link
* AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
- * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+ * AsynchronousFileChannel.open} method.
* A provider that does not support all the features required to construct
* an asynchronous file channel throws {@code UnsupportedOperationException}.
* The default provider is required to support the creation of asynchronous
@@ -399,17 +485,17 @@ public abstract class FileSystemProvider {
* method throws {@code UnsupportedOperationException}.
*
* @param path
- * The path of the file to open or create
+ * the path of the file to open or create
* @param options
- * Options specifying how the file is opened
+ * options specifying how the file is opened
* @param executor
- * The thread pool or {@code null} to associate the channel with
+ * the thread pool or {@code null} to associate the channel with
* the default thread pool
* @param attrs
- * An optional list of file attributes to set atomically when
+ * an optional list of file attributes to set atomically when
* creating the file
*
- * @return A new asynchronous file channel
+ * @return a new asynchronous file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
@@ -434,4 +520,569 @@ public abstract class FileSystemProvider {
{
throw new UnsupportedOperationException();
}
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file. This method works in exactly the manner specified by the {@link
+ * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public abstract SeekableByteChannel newByteChannel(Path path,
+ Set extends OpenOption> options, FileAttribute>... attrs) throws IOException;
+
+ /**
+ * Opens a directory, returning a {@code DirectoryStream} to iterate over
+ * the entries in the directory. This method works in exactly the manner
+ * specified by the {@link
+ * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+ * method.
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public abstract DirectoryStream The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists (optional specific
+ * exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}("symbolic")
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public void createSymbolicLink(Path link, Path target, FileAttribute>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file. This method
+ * works in exactly the manner specified by the {@link Files#createLink}
+ * method.
+ *
+ * The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}("hard")
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a file. This method works in exactly the manner specified by the
+ * {@link Files#delete} method.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @throws NoSuchFileException
+ * if the file does not exist (optional specific exception)
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty (optional specific
+ * exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public abstract void delete(Path path) throws IOException;
+
+ /**
+ * Deletes a file if it exists. This method works in exactly the manner
+ * specified by the {@link Files#deleteIfExists} method.
+ *
+ * The default implementation of this method simply invokes {@link
+ * #delete} ignoring the {@code NoSuchFileException} when the file does not
+ * exist. It may be overridden where appropriate.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty (optional specific
+ * exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public boolean deleteIfExists(Path path) throws IOException {
+ try {
+ delete(path);
+ return true;
+ } catch (NoSuchFileException ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads the target of a symbolic link. This method works in exactly the
+ * manner specified by the {@link Files#readSymbolicLink} method.
+ *
+ * The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copy a file to a target file. This method works in exactly the manner
+ * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+ * except that both the source and target paths must be associated with
+ * this provider.
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified (optional
+ * specific exception)
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public abstract void copy(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Move or rename a file to a target file. This method works in exactly the
+ * manner specified by the {@link Files#move} method except that both the
+ * source and target paths must be associated with this provider.
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified (optional
+ * specific exception)
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * (optional specific exception)
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ public abstract void move(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Tests if two paths locate the same file. This method works in exactly the
+ * manner specified by the {@link Files#isSameFile} method.
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths locate the same file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to both files.
+ */
+ public abstract boolean isSameFile(Path path, Path path2)
+ throws IOException;
+
+ /**
+ * Tells whether or not a file is considered hidden. This method
+ * works in exactly the manner specified by the {@link Files#isHidden}
+ * method.
+ *
+ * This method is invoked by the {@link Files#isHidden isHidden} method.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public abstract boolean isHidden(Path path) throws IOException;
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located. This method works in exactly the manner specified by the
+ * {@link Files#getFileStore} method.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file store where the file is stored
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file, and in
+ * addition it checks {@link RuntimePermission}
+ * ("getFileStoreAttributes")
+ */
+ public abstract FileStore getFileStore(Path path) throws IOException;
+
+ /**
+ * Checks the existence, and optionally the accessibility, of a file.
+ *
+ * This method may be used by the {@link Files#isReadable isReadable},
+ * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+ * isExecutable} methods to check the accessibility of a file.
+ *
+ * This method checks the existence of a file and that this Java virtual
+ * machine has appropriate privileges that would allow it access the file
+ * according to all of access modes specified in the {@code modes} parameter
+ * as follows:
+ *
+ * If the {@code modes} parameter is of length zero, then the existence
+ * of the file is checked.
+ *
+ * This method follows symbolic links if the file referenced by this
+ * object is a symbolic link. Depending on the implementation, this method
+ * may require to read file permissions, access control lists, or other
+ * file attributes in order to check the effective access to the file. To
+ * determine the effective access to a file may require access to several
+ * attributes and so in some implementations this method may not be atomic
+ * with respect to other file system operations.
+ *
+ * @param path
+ * the path to the file to check
+ * @param modes
+ * The access modes to check; may have zero elements
+ *
+ * @throws UnsupportedOperationException
+ * an implementation is required to support checking for
+ * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+ * exception is specified to allow for the {@code Access} enum to
+ * be extended in future releases.
+ * @throws NoSuchFileException
+ * if a file does not exist (optional specific exception)
+ * @throws AccessDeniedException
+ * the requested access would be denied or the access cannot be
+ * determined because the Java virtual machine has insufficient
+ * privileges or other reasons. (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked when checking read access to the file or only the
+ * existence of the file, the {@link SecurityManager#checkWrite(String)
+ * checkWrite} is invoked when checking write access to the file,
+ * and {@link SecurityManager#checkExec(String) checkExec} is invoked
+ * when checking execute access.
+ */
+ public abstract void checkAccess(Path path, AccessMode... modes)
+ throws IOException;
+
+ /**
+ * Returns a file attribute view of a given type. This method works in
+ * exactly the manner specified by the {@link Files#getFileAttributeView}
+ * method.
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a file attribute view of the specified type, or {@code null} if
+ * the attribute view type is not available
+ */
+ public abstract
- * boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
- *
- *
- *
- * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
- * Attributes.setLastModifiedTime(file, now);
- *
- *
- * @param file
- * A file reference that locates the file
- * @param lastModifiedTime
- * The new last modified time
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastModifiedTime(FileRef file,
- FileTime lastModifiedTime)
- throws IOException
- {
- if (lastModifiedTime == null)
- throw new NullPointerException("'lastModifiedTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(lastModifiedTime, null, null);
- }
-
- /**
- * Updates a file's last access time attribute. The file time is converted
- * to the epoch and precision supported by the file system. Converting from
- * finer to coarser granularities result in precision loss. The behavior of
- * this method when attempting to set a timestamp to a value that is outside
- * the range supported by the underlying file store is not defined. It may
- * or not fail by throwing an {@code IOException}.
- *
- *
+ * Path path = ...
+ * FileTime time = ...
+ * Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, null, time);
+ *
+ *
* @param lastModifiedTime
* the new last modified time, or {@code null} to not change the
* value
@@ -160,6 +168,8 @@ public interface BasicFileAttributeView
* In the case of the default provider, a security manager is
* installed, its {@link SecurityManager#checkWrite(String) checkWrite}
* method is invoked to check write access to the file
+ *
+ * @see java.nio.file.Files#setLastModifiedTime
*/
void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
diff --git a/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java b/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
index 31e076b9286a8851225924b4b003505652822ece..aa5d2f56156c0eccfe0edbb60b52cb2d6fb50841 100644
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
@@ -34,8 +34,8 @@ package java.nio.file.attribute;
*
*
- * FileRef file = ...
- * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * Path file = ...
+ * BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
*
*
* @since 1.7
@@ -48,25 +48,40 @@ public interface BasicFileAttributes {
/**
* Returns the time of last modification.
*
+ *
+ * Path file = ...
+ * DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ *
*
* @since 1.7
- *
- * @see Attributes#readDosFileAttributes
*/
public interface DosFileAttributes
diff --git a/src/share/classes/java/nio/file/attribute/FileAttribute.java b/src/share/classes/java/nio/file/attribute/FileAttribute.java
index d8c32fd7bbeb6f912815ca4e0b85881f80c48880..cd11d43dde8b67071e960e51e10f0bb5d953a6b3 100644
--- a/src/share/classes/java/nio/file/attribute/FileAttribute.java
+++ b/src/share/classes/java/nio/file/attribute/FileAttribute.java
@@ -28,8 +28,8 @@ package java.nio.file.attribute;
/**
* An object that encapsulates the value of a file attribute that can be set
* atomically when creating a new file or directory by invoking the {@link
- * java.nio.file.Path#createFile createFile} or {@link
- * java.nio.file.Path#createDirectory createDirectory} methods.
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
*
* @param
- *
- *
- *
- *
- *
- * Name
- * Type
- *
- *
- * "totalSpace"
- * {@link Long}
- *
- *
- * "usableSpace"
- * {@link Long}
- *
- *
- * "unallocatedSpace"
- * {@link Long}
- *
- * FileRef file = ...
- * PosixFileAttributes attrs = file.getFileAttributeView(PosixFileAttributeView.class)
+ * Path file = ...
+ * PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
* .readAttributes();
* System.out.format("%s %s%n",
* attrs.owner().getName(),
@@ -90,12 +90,12 @@ import java.io.IOException;
*
*
*
- *
*
* Setting Initial Permissions
*
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* String name = "user.mimetype";
* ByteBuffer buf = ByteBuffer.allocate(view.size(name));
* view.read(name, buf);
@@ -189,8 +189,8 @@ public interface UserDefinedFileAttributeView
*
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
*
*
diff --git a/src/share/classes/java/nio/file/attribute/package-info.java b/src/share/classes/java/nio/file/attribute/package-info.java
index a82881176dfa5642ddf01df336f72c21596d19a2..0f06fded673496c4ed2534d33a65659d876b6063 100644
--- a/src/share/classes/java/nio/file/attribute/package-info.java
+++ b/src/share/classes/java/nio/file/attribute/package-info.java
@@ -46,8 +46,6 @@
* Can read or update user-defined file attributes
*
- * {@link java.nio.file.attribute.FileStoreAttributeView}
* Can read or update file system attributes
*
*
* {@link java.nio.file.attribute.FileStoreSpaceAttributeView}
- * Can read file system space usage related attributes Symbolic Links
* Many operating systems and file systems support for symbolic links.
@@ -43,7 +43,7 @@
* target of the link. This package includes support for symbolic links where
* implementations provide these semantics. File systems may support other types
* that are semantically close but support for these other types of links is
- * not included in this package.
+ * not included in this package. Interoperability
* The {@link java.io.File} class defines the {@link java.io.File#toPath
@@ -52,7 +52,7 @@
* {@code Path} can be used to operate on the same file as the {@code File}
* object. The {@code Path} specification provides further information
* on the interoperability between {@code Path}
- * and {@code java.io.File} objects.
+ * and {@code java.io.File} objects. Visibility
* The view of the files and file system provided by classes in this package are
@@ -63,7 +63,7 @@
* network-filesystem protocols. This is true regardless of the language in which
* these other programs are written, and whether they are running on the same machine
* or on some other machine. The exact nature of any such inconsistencies are
- * system-dependent and are therefore unspecified.
+ * system-dependent and are therefore unspecified. Synchronized I/O File Integrity
* The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link
@@ -80,14 +80,14 @@
* crash. If the file does not reside on a local device then no such guarantee
* is made. Whether this guarantee is possible with other {@link
* java.nio.file.spi.FileSystemProvider provider} implementations is provider
- * specific.
+ * specific. General Exceptions
* Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with a collection containing a {@code null} element will
- * cause a {@code NullPointerException}, unless otherwise specified.
+ * cause a {@code NullPointerException}, unless otherwise specified. Optional Specific Exceptions
* Most of the methods defined by classes in this package that access the
diff --git a/src/share/classes/java/nio/file/spi/FileSystemProvider.java b/src/share/classes/java/nio/file/spi/FileSystemProvider.java
index a267ad11bba844cbd67044a03b0a00d97b060316..ad285bd6ddb30dfb3414d626931a6413a9354e92 100644
--- a/src/share/classes/java/nio/file/spi/FileSystemProvider.java
+++ b/src/share/classes/java/nio/file/spi/FileSystemProvider.java
@@ -26,17 +26,21 @@
package java.nio.file.spi;
import java.nio.file.*;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.io.IOException;
/**
- * Service-provider class for file systems.
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
*
*
+ *
+ *
+ *
+ * Value Description
+ *
+ * {@link AccessMode#READ READ}
+ * Checks that the file exists and that the Java virtual machine has
+ * permission to read the file.
+ *
+ *
+ * {@link AccessMode#WRITE WRITE}
+ * Checks that the file exists and that the Java virtual machine has
+ * permission to write to the file,
+ *
+ *
+ * {@link AccessMode#EXECUTE EXECUTE}
+ * Checks that the file exists and that the Java virtual machine has
+ * permission to {@link Runtime#exec execute} the file. The semantics
+ * may differ when checking access to a directory. For example, on UNIX
+ * systems, checking for {@code EXECUTE} access checks that the Java
+ * virtual machine has permission to search the directory in order to
+ * access file or subdirectories.
+ *