History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/nio/file/Files.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/nio/file/Files.java+3120−0
@@ -0,0 +1,3120 @@
1+/*
2+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.nio.file;
27+
28+import java.nio.file.attribute.*;
29+import java.nio.file.spi.FileSystemProvider;
30+import java.nio.file.spi.FileTypeDetector;
31+import java.nio.channels.SeekableByteChannel;
32+import java.io.InputStream;
33+import java.io.OutputStream;
34+import java.io.Reader;
35+import java.io.Writer;
36+import java.io.BufferedReader;
37+import java.io.BufferedWriter;
38+import java.io.InputStreamReader;
39+import java.io.OutputStreamWriter;
40+import java.io.IOException;
41+import java.util.*;
42+import java.security.AccessController;
43+import java.security.PrivilegedAction;
44+import java.nio.charset.Charset;
45+import java.nio.charset.CharsetDecoder;
46+import java.nio.charset.CharsetEncoder;
47+
48+/**
49+ * This class consists exclusively of static methods that operate on files,
50+ * directories, or other types of files.
51+ *
52+ * <p> In most cases, the methods defined here will delegate to the associated
53+ * file system provider to perform the file operations.
54+ *
55+ * @since 1.7
56+ */
57+
58+public final class Files {
59+ private Files() { }
60+
61+ /**
62+ * Returns the {@code FileSystemProvider} to delegate to.
63+ */
64+ private static FileSystemProvider provider(Path path) {
65+ return path.getFileSystem().provider();
66+ }
67+
68+ // -- File contents --
69+
70+ /**
71+ * Opens a file, returning an input stream to read from the file. The stream
72+ * will not be buffered, and is not required to support the {@link
73+ * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
74+ * stream will be safe for access by multiple concurrent threads. Reading
75+ * commences at the beginning of the file. Whether the returned stream is
76+ * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
77+ * file system provider specific and therefore not specified.
78+ *
79+ * <p> The {@code options} parameter determines how the file is opened.
80+ * If no options are present then it is equivalent to opening the file with
81+ * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
82+ * READ} option, an implementation may also support additional implementation
83+ * specific options.
84+ *
85+ * @param path
86+ * the path to the file to open
87+ * @param options
88+ * options specifying how the file is opened
89+ *
90+ * @return a new input stream
91+ *
92+ * @throws IllegalArgumentException
93+ * if an invalid combination of options is specified
94+ * @throws UnsupportedOperationException
95+ * if an unsupported option is specified
96+ * @throws IOException
97+ * if an I/O error occurs
98+ * @throws SecurityException
99+ * In the case of the default provider, and a security manager is
100+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
101+ * method is invoked to check read access to the file.
102+ */
103+ public static InputStream newInputStream(Path path, OpenOption... options)
104+ throws IOException
105+ {
106+ return provider(path).newInputStream(path, options);
107+ }
108+
109+ /**
110+ * Opens or creates a file, returning an output stream that may be used to
111+ * write bytes to the file. The resulting stream will not be buffered. The
112+ * stream will be safe for access by multiple concurrent threads. Whether
113+ * the returned stream is <i>asynchronously closeable</i> and/or
114+ * <i>interruptible</i> is highly file system provider specific and
115+ * therefore not specified.
116+ *
117+ * <p> This method opens or creates a file in exactly the manner specified
118+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
119+ * method with the exception that the {@link StandardOpenOption#READ READ}
120+ * option may not be present in the array of options. If no options are
121+ * present then this method works as if the {@link StandardOpenOption#CREATE
122+ * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
123+ * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
124+ * words, it opens the file for writing, creating the file if it doesn't
125+ * exist, or initially truncating an existing {@link #isRegularFile
126+ * regular-file} to a size of {@code 0} if it exists.
127+ *
128+ * <p> <b>Usage Examples:</b>
129+ * <pre>
130+ * Path path = ...
131+ *
132+ * // truncate and overwrite an existing file, or create the file if
133+ * // it doesn't initially exist
134+ * OutputStream out = Files.newOutputStream(path);
135+ *
136+ * // append to an existing file, fail if the file does not exist
137+ * out = Files.newOutputStream(path, APPEND);
138+ *
139+ * // append to an existing file, create file if it doesn't initially exist
140+ * out = Files.newOutputStream(path, CREATE, APPEND);
141+ *
142+ * // always create new file, failing if it already exists
143+ * out = Files.newOutputStream(path, CREATE_NEW);
144+ * </pre>
145+ *
146+ * @param path
147+ * the path to the file to open or create
148+ * @param options
149+ * options specifying how the file is opened
150+ *
151+ * @return a new output stream
152+ *
153+ * @throws IllegalArgumentException
154+ * if {@code options} contains an invalid combination of options
155+ * @throws UnsupportedOperationException
156+ * if an unsupported option is specified
157+ * @throws IOException
158+ * if an I/O error occurs
159+ * @throws SecurityException
160+ * In the case of the default provider, and a security manager is
161+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
162+ * method is invoked to check write access to the file. The {@link
163+ * SecurityManager#checkDelete(String) checkDelete} method is
164+ * invoked to check delete access if the file is opened with the
165+ * {@code DELETE_ON_CLOSE} option.
166+ */
167+ public static OutputStream newOutputStream(Path path, OpenOption... options)
168+ throws IOException
169+ {
170+ return provider(path).newOutputStream(path, options);
171+ }
172+
173+ /**
174+ * Opens or creates a file, returning a seekable byte channel to access the
175+ * file.
176+ *
177+ * <p> The {@code options} parameter determines how the file is opened.
178+ * The {@link StandardOpenOption#READ READ} and {@link
179+ * StandardOpenOption#WRITE WRITE} options determine if the file should be
180+ * opened for reading and/or writing. If neither option (or the {@link
181+ * StandardOpenOption#APPEND APPEND} option) is present then the file is
182+ * opened for reading. By default reading or writing commence at the
183+ * beginning of the file.
184+ *
185+ * <p> In the addition to {@code READ} and {@code WRITE}, the following
186+ * options may be present:
187+ *
188+ * <table border=1 cellpadding=5 summary="">
189+ * <tr> <th>Option</th> <th>Description</th> </tr>
190+ * <tr>
191+ * <td> {@link StandardOpenOption#APPEND APPEND} </td>
192+ * <td> If this option is present then the file is opened for writing and
193+ * each invocation of the channel's {@code write} method first advances
194+ * the position to the end of the file and then writes the requested
195+ * data. Whether the advancement of the position and the writing of the
196+ * data are done in a single atomic operation is system-dependent and
197+ * therefore unspecified. This option may not be used in conjunction
198+ * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
199+ * </tr>
200+ * <tr>
201+ * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
202+ * <td> If this option is present then the existing file is truncated to
203+ * a size of 0 bytes. This option is ignored when the file is opened only
204+ * for reading. </td>
205+ * </tr>
206+ * <tr>
207+ * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
208+ * <td> If this option is present then a new file is created, failing if
209+ * the file already exists or is a symbolic link. When creating a file the
210+ * check for the existence of the file and the creation of the file if it
211+ * does not exist is atomic with respect to other file system operations.
212+ * This option is ignored when the file is opened only for reading. </td>
213+ * </tr>
214+ * <tr>
215+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
216+ * <td> If this option is present then an existing file is opened if it
217+ * exists, otherwise a new file is created. This option is ignored if the
218+ * {@code CREATE_NEW} option is also present or the file is opened only
219+ * for reading. </td>
220+ * </tr>
221+ * <tr>
222+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
223+ * <td> When this option is present then the implementation makes a
224+ * <em>best effort</em> attempt to delete the file when closed by the
225+ * {@link SeekableByteChannel#close close} method. If the {@code close}
226+ * method is not invoked then a <em>best effort</em> attempt is made to
227+ * delete the file when the Java virtual machine terminates. </td>
228+ * </tr>
229+ * <tr>
230+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
231+ * <td> When creating a new file this option is a <em>hint</em> that the
232+ * new file will be sparse. This option is ignored when not creating
233+ * a new file. </td>
234+ * </tr>
235+ * <tr>
236+ * <td> {@link StandardOpenOption#SYNC SYNC} </td>
237+ * <td> Requires that every update to the file's content or metadata be
238+ * written synchronously to the underlying storage device. (see <a
239+ * href="package-summary.html#integrity"> Synchronized I/O file
240+ * integrity</a>). </td>
241+ * <tr>
242+ * <tr>
243+ * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
244+ * <td> Requires that every update to the file's content be written
245+ * synchronously to the underlying storage device. (see <a
246+ * href="package-summary.html#integrity"> Synchronized I/O file
247+ * integrity</a>). </td>
248+ * </tr>
249+ * </table>
250+ *
251+ * <p> An implementation may also support additional implementation specific
252+ * options.
253+ *
254+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
255+ * file-attributes} to set atomically when a new file is created.
256+ *
257+ * <p> In the case of the default provider, the returned seekable byte channel
258+ * is a {@link java.nio.channels.FileChannel}.
259+ *
260+ * <p> <b>Usage Examples:</b>
261+ * <pre>
262+ * Path path = ...
263+ *
264+ * // open file for reading
265+ * ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
266+ *
267+ * // open file for writing to the end of an existing file, creating
268+ * // the file if it doesn't already exist
269+ * WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
270+ *
271+ * // create file with initial permissions, opening it for both reading and writing
272+ * {@code FileAttribute<<SetPosixFilePermission>> perms = ...}
273+ * SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
274+ * </pre>
275+ *
276+ * @param path
277+ * the path to the file to open or create
278+ * @param options
279+ * options specifying how the file is opened
280+ * @param attrs
281+ * an optional list of file attributes to set atomically when
282+ * creating the file
283+ *
284+ * @return a new seekable byte channel
285+ *
286+ * @throws IllegalArgumentException
287+ * if the set contains an invalid combination of options
288+ * @throws UnsupportedOperationException
289+ * if an unsupported open option is specified or the array contains
290+ * attributes that cannot be set atomically when creating the file
291+ * @throws FileAlreadyExistsException
292+ * if a file of that name already exists and the {@link
293+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
294+ * <i>(optional specific exception)</i>
295+ * @throws IOException
296+ * if an I/O error occurs
297+ * @throws SecurityException
298+ * In the case of the default provider, and a security manager is
299+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
300+ * method is invoked to check read access to the path if the file is
301+ * opened for reading. The {@link SecurityManager#checkWrite(String)
302+ * checkWrite} method is invoked to check write access to the path
303+ * if the file is opened for writing. The {@link
304+ * SecurityManager#checkDelete(String) checkDelete} method is
305+ * invoked to check delete access if the file is opened with the
306+ * {@code DELETE_ON_CLOSE} option.
307+ *
308+ * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
309+ */
310+ public static SeekableByteChannel newByteChannel(Path path,
311+ Set<? extends OpenOption> options,
312+ FileAttribute<?>... attrs)
313+ throws IOException
314+ {
315+ return provider(path).newByteChannel(path, options, attrs);
316+ }
317+
318+ /**
319+ * Opens or creates a file, returning a seekable byte channel to access the
320+ * file.
321+ *
322+ * <p> This method opens or creates a file in exactly the manner specified
323+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
324+ * method.
325+ *
326+ * @param path
327+ * the path to the file to open or create
328+ * @param options
329+ * options specifying how the file is opened
330+ *
331+ * @return a new seekable byte channel
332+ *
333+ * @throws IllegalArgumentException
334+ * if the set contains an invalid combination of options
335+ * @throws UnsupportedOperationException
336+ * if an unsupported open option is specified
337+ * @throws FileAlreadyExistsException
338+ * if a file of that name already exists and the {@link
339+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
340+ * <i>(optional specific exception)</i>
341+ * @throws IOException
342+ * if an I/O error occurs
343+ * @throws SecurityException
344+ * In the case of the default provider, and a security manager is
345+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
346+ * method is invoked to check read access to the path if the file is
347+ * opened for reading. The {@link SecurityManager#checkWrite(String)
348+ * checkWrite} method is invoked to check write access to the path
349+ * if the file is opened for writing. The {@link
350+ * SecurityManager#checkDelete(String) checkDelete} method is
351+ * invoked to check delete access if the file is opened with the
352+ * {@code DELETE_ON_CLOSE} option.
353+ *
354+ * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
355+ */
356+ public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
357+ throws IOException
358+ {
359+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
360+ Collections.addAll(set, options);
361+ return newByteChannel(path, set);
362+ }
363+
364+ // -- Directories --
365+
366+ /**
367+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
368+ * all entries in the directory. The elements returned by the directory
369+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
370+ * Path}, each one representing an entry in the directory. The {@code Path}
371+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
372+ * name of the directory entry against {@code dir}.
373+ *
374+ * <p> When not using the try-with-resources construct, then directory
375+ * stream's {@code close} method should be invoked after iteration is
376+ * completed so as to free any resources held for the open directory.
377+ *
378+ * <p> When an implementation supports operations on entries in the
379+ * directory that execute in a race-free manner then the returned directory
380+ * stream is a {@link SecureDirectoryStream}.
381+ *
382+ * @param dir
383+ * the path to the directory
384+ *
385+ * @return a new and open {@code DirectoryStream} object
386+ *
387+ * @throws NotDirectoryException
388+ * if the file could not otherwise be opened because it is not
389+ * a directory <i>(optional specific exception)</i>
390+ * @throws IOException
391+ * if an I/O error occurs
392+ * @throws SecurityException
393+ * In the case of the default provider, and a security manager is
394+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
395+ * method is invoked to check read access to the directory.
396+ */
397+ public static DirectoryStream<Path> newDirectoryStream(Path dir)
398+ throws IOException
399+ {
400+ return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
401+ @Override
402+ public boolean accept(Path entry) {
403+ return true;
404+ }
405+ });
406+ }
407+
408+ /**
409+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
410+ * the entries in the directory. The elements returned by the directory
411+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
412+ * Path}, each one representing an entry in the directory. The {@code Path}
413+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
414+ * name of the directory entry against {@code dir}. The entries returned by
415+ * the iterator are filtered by matching the {@code String} representation
416+ * of their file names against the given <em>globbing</em> pattern.
417+ *
418+ * <p> For example, suppose we want to iterate over the files ending with
419+ * ".java" in a directory:
420+ * <pre>
421+ * Path dir = ...
422+ * try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, "*.java")) {
423+ * :
424+ * }
425+ * </pre>
426+ *
427+ * <p> The globbing pattern is specified by the {@link
428+ * FileSystem#getPathMatcher getPathMatcher} method.
429+ *
430+ * <p> When not using the try-with-resources construct, then directory
431+ * stream's {@code close} method should be invoked after iteration is
432+ * completed so as to free any resources held for the open directory.
433+ *
434+ * <p> When an implementation supports operations on entries in the
435+ * directory that execute in a race-free manner then the returned directory
436+ * stream is a {@link SecureDirectoryStream}.
437+ *
438+ * @param dir
439+ * the path to the directory
440+ * @param glob
441+ * the glob pattern
442+ *
443+ * @return a new and open {@code DirectoryStream} object
444+ *
445+ * @throws java.util.regex.PatternSyntaxException
446+ * if the pattern is invalid
447+ * @throws NotDirectoryException
448+ * if the file could not otherwise be opened because it is not
449+ * a directory <i>(optional specific exception)</i>
450+ * @throws IOException
451+ * if an I/O error occurs
452+ * @throws SecurityException
453+ * In the case of the default provider, and a security manager is
454+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
455+ * method is invoked to check read access to the directory.
456+ */
457+ public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
458+ throws IOException
459+ {
460+ // avoid creating a matcher if all entries are required.
461+ if (glob.equals("*"))
462+ return newDirectoryStream(dir);
463+
464+ // create a matcher and return a filter that uses it.
465+ FileSystem fs = dir.getFileSystem();
466+ final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
467+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
468+ @Override
469+ public boolean accept(Path entry) {
470+ return matcher.matches(entry.getFileName());
471+ }
472+ };
473+ return fs.provider().newDirectoryStream(dir, filter);
474+ }
475+
476+ /**
477+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
478+ * the entries in the directory. The elements returned by the directory
479+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
480+ * Path}, each one representing an entry in the directory. The {@code Path}
481+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
482+ * name of the directory entry against {@code dir}. The entries returned by
483+ * the iterator are filtered by the given {@link DirectoryStream.Filter
484+ * filter}.
485+ *
486+ * <p> When not using the try-with-resources construct, then directory
487+ * stream's {@code close} method should be invoked after iteration is
488+ * completed so as to free any resources held for the open directory.
489+ *
490+ * <p> Where the filter terminates due to an uncaught error or runtime
491+ * exception then it is propagated to the {@link Iterator#hasNext()
492+ * hasNext} or {@link Iterator#next() next} method. Where an {@code
493+ * IOException} is thrown, it results in the {@code hasNext} or {@code
494+ * next} method throwing a {@link DirectoryIteratorException} with the
495+ * {@code IOException} as the cause.
496+ *
497+ * <p> When an implementation supports operations on entries in the
498+ * directory that execute in a race-free manner then the returned directory
499+ * stream is a {@link SecureDirectoryStream}.
500+ *
501+ * <p> <b>Usage Example:</b>
502+ * Suppose we want to iterate over the files in a directory that are
503+ * larger than 8K.
504+ * <pre>
505+ * DirectoryStream.Filter&lt;Path&gt; filter = new DirectoryStream.Filter&lt;Path&gt;() {
506+ * public boolean accept(Path file) throws IOException {
507+ * return (Files.size(file) > 8192L);
508+ * }
509+ * };
510+ * Path dir = ...
511+ * try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, filter)) {
512+ * :
513+ * }
514+ * </pre>
515+ *
516+ * @param dir
517+ * the path to the directory
518+ * @param filter
519+ * the directory stream filter
520+ *
521+ * @return a new and open {@code DirectoryStream} object
522+ *
523+ * @throws NotDirectoryException
524+ * if the file could not otherwise be opened because it is not
525+ * a directory <i>(optional specific exception)</i>
526+ * @throws IOException
527+ * if an I/O error occurs
528+ * @throws SecurityException
529+ * In the case of the default provider, and a security manager is
530+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
531+ * method is invoked to check read access to the directory.
532+ */
533+ public static DirectoryStream<Path> newDirectoryStream(Path dir,
534+ DirectoryStream.Filter<? super Path> filter)
535+ throws IOException
536+ {
537+ return provider(dir).newDirectoryStream(dir, filter);
538+ }
539+
540+ // -- Creation and deletion --
541+
542+ /**
543+ * Creates a new and empty file, failing if the file already exists. The
544+ * check for the existence of the file and the creation of the new file if
545+ * it does not exist are a single operation that is atomic with respect to
546+ * all other filesystem activities that might affect the directory.
547+ *
548+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
549+ * file-attributes} to set atomically when creating the file. Each attribute
550+ * is identified by its {@link FileAttribute#name name}. If more than one
551+ * attribute of the same name is included in the array then all but the last
552+ * occurrence is ignored.
553+ *
554+ * @param path
555+ * the path to the file to create
556+ * @param attrs
557+ * an optional list of file attributes to set atomically when
558+ * creating the file
559+ *
560+ * @return the file
561+ *
562+ * @throws UnsupportedOperationException
563+ * if the array contains an attribute that cannot be set atomically
564+ * when creating the file
565+ * @throws FileAlreadyExistsException
566+ * if a file of that name already exists
567+ * <i>(optional specific exception)</i>
568+ * @throws IOException
569+ * if an I/O error occurs or the parent directory does not exist
570+ * @throws SecurityException
571+ * In the case of the default provider, and a security manager is
572+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
573+ * method is invoked to check write access to the new file.
574+ */
575+ public static Path createFile(Path path, FileAttribute<?>... attrs)
576+ throws IOException
577+ {
578+ EnumSet<StandardOpenOption> options =
579+ EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
580+ newByteChannel(path, options, attrs).close();
581+ return path;
582+ }
583+
584+ /**
585+ * Creates a new directory. The check for the existence of the file and the
586+ * creation of the directory if it does not exist are a single operation
587+ * that is atomic with respect to all other filesystem activities that might
588+ * affect the directory. The {@link #createDirectories createDirectories}
589+ * method should be used where it is required to create all nonexistent
590+ * parent directories first.
591+ *
592+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
593+ * file-attributes} to set atomically when creating the directory. Each
594+ * attribute is identified by its {@link FileAttribute#name name}. If more
595+ * than one attribute of the same name is included in the array then all but
596+ * the last occurrence is ignored.
597+ *
598+ * @param dir
599+ * the directory to create
600+ * @param attrs
601+ * an optional list of file attributes to set atomically when
602+ * creating the directory
603+ *
604+ * @return the directory
605+ *
606+ * @throws UnsupportedOperationException
607+ * if the array contains an attribute that cannot be set atomically
608+ * when creating the directory
609+ * @throws FileAlreadyExistsException
610+ * if a directory could not otherwise be created because a file of
611+ * that name already exists <i>(optional specific exception)</i>
612+ * @throws IOException
613+ * if an I/O error occurs or the parent directory does not exist
614+ * @throws SecurityException
615+ * In the case of the default provider, and a security manager is
616+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
617+ * method is invoked to check write access to the new directory.
618+ */
619+ public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
620+ throws IOException
621+ {
622+ provider(dir).createDirectory(dir, attrs);
623+ return dir;
624+ }
625+
626+ /**
627+ * Creates a directory by creating all nonexistent parent directories first.
628+ * Unlike the {@link #createDirectory createDirectory} method, an exception
629+ * is not thrown if the directory could not be created because it already
630+ * exists.
631+ *
632+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
633+ * file-attributes} to set atomically when creating the nonexistent
634+ * directories. Each file attribute is identified by its {@link
635+ * FileAttribute#name name}. If more than one attribute of the same name is
636+ * included in the array then all but the last occurrence is ignored.
637+ *
638+ * <p> If this method fails, then it may do so after creating some, but not
639+ * all, of the parent directories.
640+ *
641+ * @param dir
642+ * the directory to create
643+ *
644+ * @param attrs
645+ * an optional list of file attributes to set atomically when
646+ * creating the directory
647+ *
648+ * @return the directory
649+ *
650+ * @throws UnsupportedOperationException
651+ * if the array contains an attribute that cannot be set atomically
652+ * when creating the directory
653+ * @throws FileAlreadyExistsException
654+ * if {@code dir} exists but is not a directory <i>(optional specific
655+ * exception)</i>
656+ * @throws IOException
657+ * if an I/O error occurs
658+ * @throws SecurityException
659+ * in the case of the default provider, and a security manager is
660+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
661+ * method is invoked prior to attempting to create a directory and
662+ * its {@link SecurityManager#checkRead(String) checkRead} is
663+ * invoked for each parent directory that is checked. If {@code
664+ * dir} is not an absolute path then its {@link Path#toAbsolutePath
665+ * toAbsolutePath} may need to be invoked to get its absolute path.
666+ * This may invoke the security manager's {@link
667+ * SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
668+ * method to check access to the system property {@code user.dir}
669+ */
670+ public static Path createDirectories(Path dir, FileAttribute<?>... attrs)
671+ throws IOException
672+ {
673+ // attempt to create the directory
674+ try {
675+ createAndCheckIsDirectory(dir, attrs);
676+ return dir;
677+ } catch (FileAlreadyExistsException x) {
678+ // file exists and is not a directory
679+ throw x;
680+ } catch (IOException x) {
681+ // parent may not exist or other reason
682+ }
683+ SecurityException se = null;
684+ try {
685+ dir = dir.toAbsolutePath();
686+ } catch (SecurityException x) {
687+ // don't have permission to get absolute path
688+ se = x;
689+ }
690+ // find a decendent that exists
691+ Path parent = dir.getParent();
692+ while (parent != null) {
693+ try {
694+ provider(parent).checkAccess(parent);
695+ break;
696+ } catch (NoSuchFileException x) {
697+ // does not exist
698+ }
699+ parent = parent.getParent();
700+ }
701+ if (parent == null) {
702+ // unable to find existing parent
703+ if (se != null)
704+ throw se;
705+ throw new IOException("Root directory does not exist");
706+ }
707+
708+ // create directories
709+ Path child = parent;
710+ for (Path name: parent.relativize(dir)) {
711+ child = child.resolve(name);
712+ createAndCheckIsDirectory(child, attrs);
713+ }
714+ return dir;
715+ }
716+
717+ /**
718+ * Used by createDirectories to attempt to create a directory. A no-op
719+ * if the directory already exists.
720+ */
721+ private static void createAndCheckIsDirectory(Path dir,
722+ FileAttribute<?>... attrs)
723+ throws IOException
724+ {
725+ try {
726+ createDirectory(dir, attrs);
727+ } catch (FileAlreadyExistsException x) {
728+ if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
729+ throw x;
730+ }
731+ }
732+
733+ /**
734+ * Creates a new empty file in the specified directory, using the given
735+ * prefix and suffix strings to generate its name. The resulting
736+ * {@code Path} is associated with the same {@code FileSystem} as the given
737+ * directory.
738+ *
739+ * <p> The details as to how the name of the file is constructed is
740+ * implementation dependent and therefore not specified. Where possible
741+ * the {@code prefix} and {@code suffix} are used to construct candidate
742+ * names in the same manner as the {@link
743+ * java.io.File#createTempFile(String,String,File)} method.
744+ *
745+ * <p> As with the {@code File.createTempFile} methods, this method is only
746+ * part of a temporary-file facility. Where used as a <em>work files</em>,
747+ * the resulting file may be opened using the {@link
748+ * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
749+ * file is deleted when the appropriate {@code close} method is invoked.
750+ * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
751+ * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
752+ * file automatically.
753+ *
754+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
755+ * file-attributes} to set atomically when creating the file. Each attribute
756+ * is identified by its {@link FileAttribute#name name}. If more than one
757+ * attribute of the same name is included in the array then all but the last
758+ * occurrence is ignored. When no file attributes are specified, then the
759+ * resulting file may have more restrictive access permissions to files
760+ * created by the {@link java.io.File#createTempFile(String,String,File)}
761+ * method.
762+ *
763+ * @param dir
764+ * the path to directory in which to create the file
765+ * @param prefix
766+ * the prefix string to be used in generating the file's name;
767+ * may be {@code null}
768+ * @param suffix
769+ * the suffix string to be used in generating the file's name;
770+ * may be {@code null}, in which case "{@code .tmp}" is used
771+ * @param attrs
772+ * an optional list of file attributes to set atomically when
773+ * creating the file
774+ *
775+ * @return the path to the newly created file that did not exist before
776+ * this method was invoked
777+ *
778+ * @throws IllegalArgumentException
779+ * if the prefix or suffix parameters cannot be used to generate
780+ * a candidate file name
781+ * @throws UnsupportedOperationException
782+ * if the array contains an attribute that cannot be set atomically
783+ * when creating the directory
784+ * @throws IOException
785+ * if an I/O error occurs or {@code dir} does not exist
786+ * @throws SecurityException
787+ * In the case of the default provider, and a security manager is
788+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
789+ * method is invoked to check write access to the file.
790+ */
791+ public static Path createTempFile(Path dir,
792+ String prefix,
793+ String suffix,
794+ FileAttribute<?>... attrs)
795+ throws IOException
796+ {
797+ return TempFileHelper.createTempFile(Objects.requireNonNull(dir),
798+ prefix, suffix, attrs);
799+ }
800+
801+ /**
802+ * Creates an empty file in the default temporary-file directory, using
803+ * the given prefix and suffix to generate its name. The resulting {@code
804+ * Path} is associated with the default {@code FileSystem}.
805+ *
806+ * <p> This method works in exactly the manner specified by the
807+ * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
808+ * the case that the {@code dir} parameter is the temporary-file directory.
809+ *
810+ * @param prefix
811+ * the prefix string to be used in generating the file's name;
812+ * may be {@code null}
813+ * @param suffix
814+ * the suffix string to be used in generating the file's name;
815+ * may be {@code null}, in which case "{@code .tmp}" is used
816+ * @param attrs
817+ * an optional list of file attributes to set atomically when
818+ * creating the file
819+ *
820+ * @return the path to the newly created file that did not exist before
821+ * this method was invoked
822+ *
823+ * @throws IllegalArgumentException
824+ * if the prefix or suffix parameters cannot be used to generate
825+ * a candidate file name
826+ * @throws UnsupportedOperationException
827+ * if the array contains an attribute that cannot be set atomically
828+ * when creating the directory
829+ * @throws IOException
830+ * if an I/O error occurs or the temporary-file directory does not
831+ * exist
832+ * @throws SecurityException
833+ * In the case of the default provider, and a security manager is
834+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
835+ * method is invoked to check write access to the file.
836+ */
837+ public static Path createTempFile(String prefix,
838+ String suffix,
839+ FileAttribute<?>... attrs)
840+ throws IOException
841+ {
842+ return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
843+ }
844+
845+ /**
846+ * Creates a new directory in the specified directory, using the given
847+ * prefix to generate its name. The resulting {@code Path} is associated
848+ * with the same {@code FileSystem} as the given directory.
849+ *
850+ * <p> The details as to how the name of the directory is constructed is
851+ * implementation dependent and therefore not specified. Where possible
852+ * the {@code prefix} is used to construct candidate names.
853+ *
854+ * <p> As with the {@code createTempFile} methods, this method is only
855+ * part of a temporary-file facility. A {@link Runtime#addShutdownHook
856+ * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
857+ * used to delete the directory automatically.
858+ *
859+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
860+ * file-attributes} to set atomically when creating the directory. Each
861+ * attribute is identified by its {@link FileAttribute#name name}. If more
862+ * than one attribute of the same name is included in the array then all but
863+ * the last occurrence is ignored.
864+ *
865+ * @param dir
866+ * the path to directory in which to create the directory
867+ * @param prefix
868+ * the prefix string to be used in generating the directory's name;
869+ * may be {@code null}
870+ * @param attrs
871+ * an optional list of file attributes to set atomically when
872+ * creating the directory
873+ *
874+ * @return the path to the newly created directory that did not exist before
875+ * this method was invoked
876+ *
877+ * @throws IllegalArgumentException
878+ * if the prefix cannot be used to generate a candidate directory name
879+ * @throws UnsupportedOperationException
880+ * if the array contains an attribute that cannot be set atomically
881+ * when creating the directory
882+ * @throws IOException
883+ * if an I/O error occurs or {@code dir} does not exist
884+ * @throws SecurityException
885+ * In the case of the default provider, and a security manager is
886+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
887+ * method is invoked to check write access when creating the
888+ * directory.
889+ */
890+ public static Path createTempDirectory(Path dir,
891+ String prefix,
892+ FileAttribute<?>... attrs)
893+ throws IOException
894+ {
895+ return TempFileHelper.createTempDirectory(Objects.requireNonNull(dir),
896+ prefix, attrs);
897+ }
898+
899+ /**
900+ * Creates a new directory in the default temporary-file directory, using
901+ * the given prefix to generate its name. The resulting {@code Path} is
902+ * associated with the default {@code FileSystem}.
903+ *
904+ * <p> This method works in exactly the manner specified by {@link
905+ * #createTempDirectory(Path,String,FileAttribute[])} method for the case
906+ * that the {@code dir} parameter is the temporary-file directory.
907+ *
908+ * @param prefix
909+ * the prefix string to be used in generating the directory's name;
910+ * may be {@code null}
911+ * @param attrs
912+ * an optional list of file attributes to set atomically when
913+ * creating the directory
914+ *
915+ * @return the path to the newly created directory that did not exist before
916+ * this method was invoked
917+ *
918+ * @throws IllegalArgumentException
919+ * if the prefix cannot be used to generate a candidate directory name
920+ * @throws UnsupportedOperationException
921+ * if the array contains an attribute that cannot be set atomically
922+ * when creating the directory
923+ * @throws IOException
924+ * if an I/O error occurs or the temporary-file directory does not
925+ * exist
926+ * @throws SecurityException
927+ * In the case of the default provider, and a security manager is
928+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
929+ * method is invoked to check write access when creating the
930+ * directory.
931+ */
932+ public static Path createTempDirectory(String prefix,
933+ FileAttribute<?>... attrs)
934+ throws IOException
935+ {
936+ return TempFileHelper.createTempDirectory(null, prefix, attrs);
937+ }
938+
939+ /**
940+ * Creates a symbolic link to a target <i>(optional operation)</i>.
941+ *
942+ * <p> The {@code target} parameter is the target of the link. It may be an
943+ * {@link Path#isAbsolute absolute} or relative path and may not exist. When
944+ * the target is a relative path then file system operations on the resulting
945+ * link are relative to the path of the link.
946+ *
947+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
948+ * attributes} to set atomically when creating the link. Each attribute is
949+ * identified by its {@link FileAttribute#name name}. If more than one attribute
950+ * of the same name is included in the array then all but the last occurrence
951+ * is ignored.
952+ *
953+ * <p> Where symbolic links are supported, but the underlying {@link FileStore}
954+ * does not support symbolic links, then this may fail with an {@link
955+ * IOException}. Additionally, some operating systems may require that the
956+ * Java virtual machine be started with implementation specific privileges to
957+ * create symbolic links, in which case this method may throw {@code IOException}.
958+ *
959+ * @param link
960+ * the path of the symbolic link to create
961+ * @param target
962+ * the target of the symbolic link
963+ * @param attrs
964+ * the array of attributes to set atomically when creating the
965+ * symbolic link
966+ *
967+ * @return the path to the symbolic link
968+ *
969+ * @throws UnsupportedOperationException
970+ * if the implementation does not support symbolic links or the
971+ * array contains an attribute that cannot be set atomically when
972+ * creating the symbolic link
973+ * @throws FileAlreadyExistsException
974+ * if a file with the name already exists <i>(optional specific
975+ * exception)</i>
976+ * @throws IOException
977+ * if an I/O error occurs
978+ * @throws SecurityException
979+ * In the case of the default provider, and a security manager
980+ * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
981+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
982+ * method denies write access to the path of the symbolic link.
983+ */
984+ public static Path createSymbolicLink(Path link, Path target,
985+ FileAttribute<?>... attrs)
986+ throws IOException
987+ {
988+ provider(link).createSymbolicLink(link, target, attrs);
989+ return link;
990+ }
991+
992+ /**
993+ * Creates a new link (directory entry) for an existing file <i>(optional
994+ * operation)</i>.
995+ *
996+ * <p> The {@code link} parameter locates the directory entry to create.
997+ * The {@code existing} parameter is the path to an existing file. This
998+ * method creates a new directory entry for the file so that it can be
999+ * accessed using {@code link} as the path. On some file systems this is
1000+ * known as creating a "hard link". Whether the file attributes are
1001+ * maintained for the file or for each directory entry is file system
1002+ * specific and therefore not specified. Typically, a file system requires
1003+ * that all links (directory entries) for a file be on the same file system.
1004+ * Furthermore, on some platforms, the Java virtual machine may require to
1005+ * be started with implementation specific privileges to create hard links
1006+ * or to create links to directories.
1007+ *
1008+ * @param link
1009+ * the link (directory entry) to create
1010+ * @param existing
1011+ * a path to an existing file
1012+ *
1013+ * @return the path to the link (directory entry)
1014+ *
1015+ * @throws UnsupportedOperationException
1016+ * if the implementation does not support adding an existing file
1017+ * to a directory
1018+ * @throws FileAlreadyExistsException
1019+ * if the entry could not otherwise be created because a file of
1020+ * that name already exists <i>(optional specific exception)</i>
1021+ * @throws IOException
1022+ * if an I/O error occurs
1023+ * @throws SecurityException
1024+ * In the case of the default provider, and a security manager
1025+ * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
1026+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
1027+ * method denies write access to either the link or the
1028+ * existing file.
1029+ */
1030+ public static Path createLink(Path link, Path existing) throws IOException {
1031+ provider(link).createLink(link, existing);
1032+ return link;
1033+ }
1034+
1035+ /**
1036+ * Deletes a file.
1037+ *
1038+ * <p> An implementation may require to examine the file to determine if the
1039+ * file is a directory. Consequently this method may not be atomic with respect
1040+ * to other file system operations. If the file is a symbolic link then the
1041+ * symbolic link itself, not the final target of the link, is deleted.
1042+ *
1043+ * <p> If the file is a directory then the directory must be empty. In some
1044+ * implementations a directory has entries for special files or links that
1045+ * are created when the directory is created. In such implementations a
1046+ * directory is considered empty when only the special entries exist.
1047+ * This method can be used with the {@link #walkFileTree walkFileTree}
1048+ * method to delete a directory and all entries in the directory, or an
1049+ * entire <i>file-tree</i> where required.
1050+ *
1051+ * <p> On some operating systems it may not be possible to remove a file when
1052+ * it is open and in use by this Java virtual machine or other programs.
1053+ *
1054+ * @param path
1055+ * the path to the file to delete
1056+ *
1057+ * @throws NoSuchFileException
1058+ * if the file does not exist <i>(optional specific exception)</i>
1059+ * @throws DirectoryNotEmptyException
1060+ * if the file is a directory and could not otherwise be deleted
1061+ * because the directory is not empty <i>(optional specific
1062+ * exception)</i>
1063+ * @throws IOException
1064+ * if an I/O error occurs
1065+ * @throws SecurityException
1066+ * In the case of the default provider, and a security manager is
1067+ * installed, the {@link SecurityManager#checkDelete(String)} method
1068+ * is invoked to check delete access to the file
1069+ */
1070+ public static void delete(Path path) throws IOException {
1071+ provider(path).delete(path);
1072+ }
1073+
1074+ /**
1075+ * Deletes a file if it exists.
1076+ *
1077+ * <p> As with the {@link #delete(Path) delete(Path)} method, an
1078+ * implementation may need to examine the file to determine if the file is a
1079+ * directory. Consequently this method may not be atomic with respect to
1080+ * other file system operations. If the file is a symbolic link, then the
1081+ * symbolic link itself, not the final target of the link, is deleted.
1082+ *
1083+ * <p> If the file is a directory then the directory must be empty. In some
1084+ * implementations a directory has entries for special files or links that
1085+ * are created when the directory is created. In such implementations a
1086+ * directory is considered empty when only the special entries exist.
1087+ *
1088+ * <p> On some operating systems it may not be possible to remove a file when
1089+ * it is open and in use by this Java virtual machine or other programs.
1090+ *
1091+ * @param path
1092+ * the path to the file to delete
1093+ *
1094+ * @return {@code true} if the file was deleted by this method; {@code
1095+ * false} if the file could not be deleted because it did not
1096+ * exist
1097+ *
1098+ * @throws DirectoryNotEmptyException
1099+ * if the file is a directory and could not otherwise be deleted
1100+ * because the directory is not empty <i>(optional specific
1101+ * exception)</i>
1102+ * @throws IOException
1103+ * if an I/O error occurs
1104+ * @throws SecurityException
1105+ * In the case of the default provider, and a security manager is
1106+ * installed, the {@link SecurityManager#checkDelete(String)} method
1107+ * is invoked to check delete access to the file.
1108+ */
1109+ public static boolean deleteIfExists(Path path) throws IOException {
1110+ return provider(path).deleteIfExists(path);
1111+ }
1112+
1113+ // -- Copying and moving files --
1114+
1115+ /**
1116+ * Copy a file to a target file.
1117+ *
1118+ * <p> This method copies a file to the target file with the {@code
1119+ * options} parameter specifying how the copy is performed. By default, the
1120+ * copy fails if the target file already exists or is a symbolic link,
1121+ * except if the source and target are the {@link #isSameFile same} file, in
1122+ * which case the method completes without copying the file. File attributes
1123+ * are not required to be copied to the target file. If symbolic links are
1124+ * supported, and the file is a symbolic link, then the final target of the
1125+ * link is copied. If the file is a directory then it creates an empty
1126+ * directory in the target location (entries in the directory are not
1127+ * copied). This method can be used with the {@link #walkFileTree
1128+ * walkFileTree} method to copy a directory and all entries in the directory,
1129+ * or an entire <i>file-tree</i> where required.
1130+ *
1131+ * <p> The {@code options} parameter may include any of the following:
1132+ *
1133+ * <table border=1 cellpadding=5 summary="">
1134+ * <tr> <th>Option</th> <th>Description</th> </tr>
1135+ * <tr>
1136+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
1137+ * <td> If the target file exists, then the target file is replaced if it
1138+ * is not a non-empty directory. If the target file exists and is a
1139+ * symbolic link, then the symbolic link itself, not the target of
1140+ * the link, is replaced. </td>
1141+ * </tr>
1142+ * <tr>
1143+ * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
1144+ * <td> Attempts to copy the file attributes associated with this file to
1145+ * the target file. The exact file attributes that are copied is platform
1146+ * and file system dependent and therefore unspecified. Minimally, the
1147+ * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
1148+ * copied to the target file if supported by both the source and target
1149+ * file store. Copying of file timestamps may result in precision
1150+ * loss. </td>
1151+ * </tr>
1152+ * <tr>
1153+ * <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
1154+ * <td> Symbolic links are not followed. If the file is a symbolic link,
1155+ * then the symbolic link itself, not the target of the link, is copied.
1156+ * It is implementation specific if file attributes can be copied to the
1157+ * new link. In other words, the {@code COPY_ATTRIBUTES} option may be
1158+ * ignored when copying a symbolic link. </td>
1159+ * </tr>
1160+ * </table>
1161+ *
1162+ * <p> An implementation of this interface may support additional
1163+ * implementation specific options.
1164+ *
1165+ * <p> Copying a file is not an atomic operation. If an {@link IOException}
1166+ * is thrown then it possible that the target file is incomplete or some of
1167+ * its file attributes have not been copied from the source file. When the
1168+ * {@code REPLACE_EXISTING} option is specified and the target file exists,
1169+ * then the target file is replaced. The check for the existence of the file
1170+ * and the creation of the new file may not be atomic with respect to other
1171+ * file system activities.
1172+ *
1173+ * <p> <b>Usage Example:</b>
1174+ * Suppose we want to copy a file into a directory, giving it the same file
1175+ * name as the source file:
1176+ * <pre>
1177+ * Path source = ...
1178+ * Path newdir = ...
1179+ * Files.copy(source, newdir.resolve(source.getFileName());
1180+ * </pre>
1181+ *
1182+ * @param source
1183+ * the path to the file to copy
1184+ * @param target
1185+ * the path to the target file (may be associated with a different
1186+ * provider to the source path)
1187+ * @param options
1188+ * options specifying how the copy should be done
1189+ *
1190+ * @return the path to the target file
1191+ *
1192+ * @throws UnsupportedOperationException
1193+ * if the array contains a copy option that is not supported
1194+ * @throws FileAlreadyExistsException
1195+ * if the target file exists but cannot be replaced because the
1196+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
1197+ * specific exception)</i>
1198+ * @throws DirectoryNotEmptyException
1199+ * the {@code REPLACE_EXISTING} option is specified but the file
1200+ * cannot be replaced because it is a non-empty directory
1201+ * <i>(optional specific exception)</i>
1202+ * @throws IOException
1203+ * if an I/O error occurs
1204+ * @throws SecurityException
1205+ * In the case of the default provider, and a security manager is
1206+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
1207+ * method is invoked to check read access to the source file, the
1208+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
1209+ * to check write access to the target file. If a symbolic link is
1210+ * copied the security manager is invoked to check {@link
1211+ * LinkPermission}{@code ("symbolic")}.
1212+ */
1213+ public static Path copy(Path source, Path target, CopyOption... options)
1214+ throws IOException
1215+ {
1216+ FileSystemProvider provider = provider(source);
1217+ if (provider(target) == provider) {
1218+ // same provider
1219+ provider.copy(source, target, options);
1220+ } else {
1221+ // different providers
1222+ CopyMoveHelper.copyToForeignTarget(source, target, options);
1223+ }
1224+ return target;
1225+ }
1226+
1227+ /**
1228+ * Move or rename a file to a target file.
1229+ *
1230+ * <p> By default, this method attempts to move the file to the target
1231+ * file, failing if the target file exists except if the source and
1232+ * target are the {@link #isSameFile same} file, in which case this method
1233+ * has no effect. If the file is a symbolic link then the symbolic link
1234+ * itself, not the target of the link, is moved. This method may be
1235+ * invoked to move an empty directory. In some implementations a directory
1236+ * has entries for special files or links that are created when the
1237+ * directory is created. In such implementations a directory is considered
1238+ * empty when only the special entries exist. When invoked to move a
1239+ * directory that is not empty then the directory is moved if it does not
1240+ * require moving the entries in the directory. For example, renaming a
1241+ * directory on the same {@link FileStore} will usually not require moving
1242+ * the entries in the directory. When moving a directory requires that its
1243+ * entries be moved then this method fails (by throwing an {@code
1244+ * IOException}). To move a <i>file tree</i> may involve copying rather
1245+ * than moving directories and this can be done using the {@link
1246+ * #copy copy} method in conjunction with the {@link
1247+ * #walkFileTree Files.walkFileTree} utility method.
1248+ *
1249+ * <p> The {@code options} parameter may include any of the following:
1250+ *
1251+ * <table border=1 cellpadding=5 summary="">
1252+ * <tr> <th>Option</th> <th>Description</th> </tr>
1253+ * <tr>
1254+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
1255+ * <td> If the target file exists, then the target file is replaced if it
1256+ * is not a non-empty directory. If the target file exists and is a
1257+ * symbolic link, then the symbolic link itself, not the target of
1258+ * the link, is replaced. </td>
1259+ * </tr>
1260+ * <tr>
1261+ * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
1262+ * <td> The move is performed as an atomic file system operation and all
1263+ * other options are ignored. If the target file exists then it is
1264+ * implementation specific if the existing file is replaced or this method
1265+ * fails by throwing an {@link IOException}. If the move cannot be
1266+ * performed as an atomic file system operation then {@link
1267+ * AtomicMoveNotSupportedException} is thrown. This can arise, for
1268+ * example, when the target location is on a different {@code FileStore}
1269+ * and would require that the file be copied, or target location is
1270+ * associated with a different provider to this object. </td>
1271+ * </table>
1272+ *
1273+ * <p> An implementation of this interface may support additional
1274+ * implementation specific options.
1275+ *
1276+ * <p> Where the move requires that the file be copied then the {@link
1277+ * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
1278+ * new file. An implementation may also attempt to copy other file
1279+ * attributes but is not required to fail if the file attributes cannot be
1280+ * copied. When the move is performed as a non-atomic operation, and a {@code
1281+ * IOException} is thrown, then the state of the files is not defined. The
1282+ * original file and the target file may both exist, the target file may be
1283+ * incomplete or some of its file attributes may not been copied from the
1284+ * original file.
1285+ *
1286+ * <p> <b>Usage Examples:</b>
1287+ * Suppose we want to rename a file to "newname", keeping the file in the
1288+ * same directory:
1289+ * <pre>
1290+ * Path source = ...
1291+ * Files.move(source, source.resolveSibling("newname"));
1292+ * </pre>
1293+ * Alternatively, suppose we want to move a file to new directory, keeping
1294+ * the same file name, and replacing any existing file of that name in the
1295+ * directory:
1296+ * <pre>
1297+ * Path source = ...
1298+ * Path newdir = ...
1299+ * Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
1300+ * </pre>
1301+ *
1302+ * @param source
1303+ * the path to the file to move
1304+ * @param target
1305+ * the path to the target file (may be associated with a different
1306+ * provider to the source path)
1307+ * @param options
1308+ * options specifying how the move should be done
1309+ *
1310+ * @return the path to the target file
1311+ *
1312+ * @throws UnsupportedOperationException
1313+ * if the array contains a copy option that is not supported
1314+ * @throws FileAlreadyExistsException
1315+ * if the target file exists but cannot be replaced because the
1316+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
1317+ * specific exception)</i>
1318+ * @throws DirectoryNotEmptyException
1319+ * the {@code REPLACE_EXISTING} option is specified but the file
1320+ * cannot be replaced because it is a non-empty directory
1321+ * <i>(optional specific exception)</i>
1322+ * @throws AtomicMoveNotSupportedException
1323+ * if the options array contains the {@code ATOMIC_MOVE} option but
1324+ * the file cannot be moved as an atomic file system operation.
1325+ * @throws IOException
1326+ * if an I/O error occurs
1327+ * @throws SecurityException
1328+ * In the case of the default provider, and a security manager is
1329+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
1330+ * method is invoked to check write access to both the source and
1331+ * target file.
1332+ */
1333+ public static Path move(Path source, Path target, CopyOption... options)
1334+ throws IOException
1335+ {
1336+ FileSystemProvider provider = provider(source);
1337+ if (provider(target) == provider) {
1338+ // same provider
1339+ provider.move(source, target, options);
1340+ } else {
1341+ // different providers
1342+ CopyMoveHelper.moveToForeignTarget(source, target, options);
1343+ }
1344+ return target;
1345+ }
1346+
1347+ // -- Miscellenous --
1348+
1349+ /**
1350+ * Reads the target of a symbolic link <i>(optional operation)</i>.
1351+ *
1352+ * <p> If the file system supports <a href="package-summary.html#links">symbolic
1353+ * links</a> then this method is used to read the target of the link, failing
1354+ * if the file is not a symbolic link. The target of the link need not exist.
1355+ * The returned {@code Path} object will be associated with the same file
1356+ * system as {@code link}.
1357+ *
1358+ * @param link
1359+ * the path to the symbolic link
1360+ *
1361+ * @return a {@code Path} object representing the target of the link
1362+ *
1363+ * @throws UnsupportedOperationException
1364+ * if the implementation does not support symbolic links
1365+ * @throws NotLinkException
1366+ * if the target could otherwise not be read because the file
1367+ * is not a symbolic link <i>(optional specific exception)</i>
1368+ * @throws IOException
1369+ * if an I/O error occurs
1370+ * @throws SecurityException
1371+ * In the case of the default provider, and a security manager
1372+ * is installed, it checks that {@code FilePermission} has been
1373+ * granted with the "{@code readlink}" action to read the link.
1374+ */
1375+ public static Path readSymbolicLink(Path link) throws IOException {
1376+ return provider(link).readSymbolicLink(link);
1377+ }
1378+
1379+ /**
1380+ * Returns the {@link FileStore} representing the file store where a file
1381+ * is located.
1382+ *
1383+ * <p> Once a reference to the {@code FileStore} is obtained it is
1384+ * implementation specific if operations on the returned {@code FileStore},
1385+ * or {@link FileStoreAttributeView} objects obtained from it, continue
1386+ * to depend on the existence of the file. In particular the behavior is not
1387+ * defined for the case that the file is deleted or moved to a different
1388+ * file store.
1389+ *
1390+ * @param path
1391+ * the path to the file
1392+ *
1393+ * @return the file store where the file is stored
1394+ *
1395+ * @throws IOException
1396+ * if an I/O error occurs
1397+ * @throws SecurityException
1398+ * In the case of the default provider, and a security manager is
1399+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
1400+ * method is invoked to check read access to the file, and in
1401+ * addition it checks {@link RuntimePermission}<tt>
1402+ * ("getFileStoreAttributes")</tt>
1403+ */
1404+ public static FileStore getFileStore(Path path) throws IOException {
1405+ return provider(path).getFileStore(path);
1406+ }
1407+
1408+ /**
1409+ * Tests if two paths locate the same file.
1410+ *
1411+ * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
1412+ * then this method returns {@code true} without checking if the file exists.
1413+ * If the two {@code Path} objects are associated with different providers
1414+ * then this method returns {@code false}. Otherwise, this method checks if
1415+ * both {@code Path} objects locate the same file, and depending on the
1416+ * implementation, may require to open or access both files.
1417+ *
1418+ * <p> If the file system and files remain static, then this method implements
1419+ * an equivalence relation for non-null {@code Paths}.
1420+ * <ul>
1421+ * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
1422+ * {@code isSameFile(f,f)} should return {@code true}.
1423+ * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
1424+ * {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
1425+ * <li>It is <i>transitive</i>: for three {@code Paths}
1426+ * {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
1427+ * {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
1428+ * {@code isSameFile(g,h)} will return return {@code true}.
1429+ * </ul>
1430+ *
1431+ * @param path
1432+ * one path to the file
1433+ * @param path2
1434+ * the other path
1435+ *
1436+ * @return {@code true} if, and only if, the two paths locate the same file
1437+ *
1438+ * @throws IOException
1439+ * if an I/O error occurs
1440+ * @throws SecurityException
1441+ * In the case of the default provider, and a security manager is
1442+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
1443+ * method is invoked to check read access to both files.
1444+ *
1445+ * @see java.nio.file.attribute.BasicFileAttributes#fileKey
1446+ */
1447+ public static boolean isSameFile(Path path, Path path2) throws IOException {
1448+ return provider(path).isSameFile(path, path2);
1449+ }
1450+
1451+ /**
1452+ * Tells whether or not a file is considered <em>hidden</em>. The exact
1453+ * definition of hidden is platform or provider dependent. On UNIX for
1454+ * example a file is considered to be hidden if its name begins with a
1455+ * period character ('.'). On Windows a file is considered hidden if it
1456+ * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
1457+ * attribute is set.
1458+ *
1459+ * <p> Depending on the implementation this method may require to access
1460+ * the file system to determine if the file is considered hidden.
1461+ *
1462+ * @param path
1463+ * the path to the file to test
1464+ *
1465+ * @return {@code true} if the file is considered hidden
1466+ *
1467+ * @throws IOException
1468+ * if an I/O error occurs
1469+ * @throws SecurityException
1470+ * In the case of the default provider, and a security manager is
1471+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
1472+ * method is invoked to check read access to the file.
1473+ */
1474+ public static boolean isHidden(Path path) throws IOException {
1475+ return provider(path).isHidden(path);
1476+ }
1477+
1478+ // lazy loading of default and installed file type detectors
1479+ private static class FileTypeDetectors{
1480+ static final FileTypeDetector defaultFileTypeDetector =
1481+ sun.nio.fs.DefaultFileTypeDetector.create();
1482+ static final List<FileTypeDetector> installeDetectors =
1483+ loadInstalledDetectors();
1484+
1485+ // loads all installed file type detectors
1486+ private static List<FileTypeDetector> loadInstalledDetectors() {
1487+ return AccessController
1488+ .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
1489+ @Override public List<FileTypeDetector> run() {
1490+ List<FileTypeDetector> list = new ArrayList<>();
1491+ ServiceLoader<FileTypeDetector> loader = ServiceLoader
1492+ .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
1493+ for (FileTypeDetector detector: loader) {
1494+ list.add(detector);
1495+ }
1496+ return list;
1497+ }});
1498+ }
1499+ }
1500+
1501+ /**
1502+ * Probes the content type of a file.
1503+ *
1504+ * <p> This method uses the installed {@link FileTypeDetector} implementations
1505+ * to probe the given file to determine its content type. Each file type
1506+ * detector's {@link FileTypeDetector#probeContentType probeContentType} is
1507+ * invoked, in turn, to probe the file type. If the file is recognized then
1508+ * the content type is returned. If the file is not recognized by any of the
1509+ * installed file type detectors then a system-default file type detector is
1510+ * invoked to guess the content type.
1511+ *
1512+ * <p> A given invocation of the Java virtual machine maintains a system-wide
1513+ * list of file type detectors. Installed file type detectors are loaded
1514+ * using the service-provider loading facility defined by the {@link ServiceLoader}
1515+ * class. Installed file type detectors are loaded using the system class
1516+ * loader. If the system class loader cannot be found then the extension class
1517+ * loader is used; If the extension class loader cannot be found then the
1518+ * bootstrap class loader is used. File type detectors are typically installed
1519+ * by placing them in a JAR file on the application class path or in the
1520+ * extension directory, the JAR file contains a provider-configuration file
1521+ * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory
1522+ * {@code META-INF/services}, and the file lists one or more fully-qualified
1523+ * names of concrete subclass of {@code FileTypeDetector } that have a zero
1524+ * argument constructor. If the process of locating or instantiating the
1525+ * installed file type detectors fails then an unspecified error is thrown.
1526+ * The ordering that installed providers are located is implementation
1527+ * specific.
1528+ *
1529+ * <p> The return value of this method is the string form of the value of a
1530+ * Multipurpose Internet Mail Extension (MIME) content type as
1531+ * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045:
1532+ * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
1533+ * Message Bodies</i></a>. The string is guaranteed to be parsable according
1534+ * to the grammar in the RFC.
1535+ *
1536+ * @param path
1537+ * the path to the file to probe
1538+ *
1539+ * @return The content type of the file, or {@code null} if the content
1540+ * type cannot be determined
1541+ *
1542+ * @throws IOException
1543+ * if an I/O error occurs
1544+ * @throws SecurityException
1545+ * If a security manager is installed and it denies an unspecified
1546+ * permission required by a file type detector implementation.
1547+ */
1548+ public static String probeContentType(Path path)
1549+ throws IOException
1550+ {
1551+ // try installed file type detectors
1552+ for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
1553+ String result = detector.probeContentType(path);
1554+ if (result != null)
1555+ return result;
1556+ }
1557+
1558+ // fallback to default
1559+ return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
1560+ }
1561+
1562+ // -- File Attributes --
1563+
1564+ /**
1565+ * Returns a file attribute view of a given type.
1566+ *
1567+ * <p> A file attribute view provides a read-only or updatable view of a
1568+ * set of file attributes. This method is intended to be used where the file
1569+ * attribute view defines type-safe methods to read or update the file
1570+ * attributes. The {@code type} parameter is the type of the attribute view
1571+ * required and the method returns an instance of that type if supported.
1572+ * The {@link BasicFileAttributeView} type supports access to the basic
1573+ * attributes of a file. Invoking this method to select a file attribute
1574+ * view of that type will always return an instance of that class.
1575+ *
1576+ * <p> The {@code options} array may be used to indicate how symbolic links
1577+ * are handled by the resulting file attribute view for the case that the
1578+ * file is a symbolic link. By default, symbolic links are followed. If the
1579+ * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
1580+ * symbolic links are not followed. This option is ignored by implementations
1581+ * that do not support symbolic links.
1582+ *
1583+ * <p> <b>Usage Example:</b>
1584+ * Suppose we want read or set a file's ACL, if supported:
1585+ * <pre>
1586+ * Path path = ...
1587+ * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
1588+ * if (view != null) {
1589+ * List&lt;AclEntry&gt acl = view.getAcl();
1590+ * :
1591+ * }
1592+ * </pre>
1593+ *
1594+ *
1595+ * @param path
1596+ * the path to the file
1597+ * @param type
1598+ * the {@code Class} object corresponding to the file attribute view
1599+ * @param options
1600+ * options indicating how symbolic links are handled
1601+ *
1602+ * @return a file attribute view of the specified type, or {@code null} if
1603+ * the attribute view type is not available
1604+ */
1605+ public static <V extends FileAttributeView> V getFileAttributeView(Path path,
1606+ Class<V> type,
1607+ LinkOption... options)
1608+ {
1609+ return provider(path).getFileAttributeView(path, type, options);
1610+ }
1611+
1612+ /**
1613+ * Reads a file's attributes as a bulk operation.
1614+ *
1615+ * <p> The {@code type} parameter is the type of the attributes required
1616+ * and this method returns an instance of that type if supported. All
1617+ * implementations support a basic set of file attributes and so invoking
1618+ * this method with a {@code type} parameter of {@code
1619+ * BasicFileAttributes.class} will not throw {@code
1620+ * UnsupportedOperationException}.
1621+ *
1622+ * <p> The {@code options} array may be used to indicate how symbolic links
1623+ * are handled for the case that the file is a symbolic link. By default,
1624+ * symbolic links are followed and the file attribute of the final target
1625+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
1626+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
1627+ *
1628+ * <p> It is implementation specific if all file attributes are read as an
1629+ * atomic operation with respect to other file system operations.
1630+ *
1631+ * <p> <b>Usage Example:</b>
1632+ * Suppose we want to read a file's attributes in bulk:
1633+ * <pre>
1634+ * Path path = ...
1635+ * BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
1636+ * </pre>
1637+ * Alternatively, suppose we want to read file's POSIX attributes without
1638+ * following symbolic links:
1639+ * <pre>
1640+ * PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
1641+ * </pre>
1642+ *
1643+ * @param path
1644+ * the path to the file
1645+ * @param type
1646+ * the {@code Class} of the file attributes required
1647+ * to read
1648+ * @param options
1649+ * options indicating how symbolic links are handled
1650+ *
1651+ * @return the file attributes
1652+ *
1653+ * @throws UnsupportedOperationException
1654+ * if an attributes of the given type are not supported
1655+ * @throws IOException
1656+ * if an I/O error occurs
1657+ * @throws SecurityException
1658+ * In the case of the default provider, a security manager is
1659+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
1660+ * method is invoked to check read access to the file. If this
1661+ * method is invoked to read security sensitive attributes then the
1662+ * security manager may be invoke to check for additional permissions.
1663+ */
1664+ public static <A extends BasicFileAttributes> A readAttributes(Path path,
1665+ Class<A> type,
1666+ LinkOption... options)
1667+ throws IOException
1668+ {
1669+ return provider(path).readAttributes(path, type, options);
1670+ }
1671+
1672+ /**
1673+ * Sets the value of a file attribute.
1674+ *
1675+ * <p> The {@code attribute} parameter identifies the attribute to be set
1676+ * and takes the form:
1677+ * <blockquote>
1678+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
1679+ * </blockquote>
1680+ * where square brackets [...] delineate an optional component and the
1681+ * character {@code ':'} stands for itself.
1682+ *
1683+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
1684+ * FileAttributeView} that identifies a set of file attributes. If not
1685+ * specified then it defaults to {@code "basic"}, the name of the file
1686+ * attribute view that identifies the basic set of file attributes common to
1687+ * many file systems. <i>attribute-name</i> is the name of the attribute
1688+ * within the set.
1689+ *
1690+ * <p> The {@code options} array may be used to indicate how symbolic links
1691+ * are handled for the case that the file is a symbolic link. By default,
1692+ * symbolic links are followed and the file attribute of the final target
1693+ * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS
1694+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
1695+ *
1696+ * <p> <b>Usage Example:</b>
1697+ * Suppose we want to set the DOS "hidden" attribute:
1698+ * <pre>
1699+ * Path path = ...
1700+ * Files.setAttribute(path, "dos:hidden", true);
1701+ * </pre>
1702+ *
1703+ * @param path
1704+ * the path to the file
1705+ * @param attribute
1706+ * the attribute to set
1707+ * @param value
1708+ * the attribute value
1709+ * @param options
1710+ * options indicating how symbolic links are handled
1711+ *
1712+ * @return the {@code path} parameter
1713+ *
1714+ * @throws UnsupportedOperationException
1715+ * if the attribute view is not available
1716+ * @throws IllegalArgumentException
1717+ * if the attribute name is not specified, or is not recognized, or
1718+ * the attribute value is of the correct type but has an
1719+ * inappropriate value
1720+ * @throws ClassCastException
1721+ * if the attribute value is not of the expected type or is a
1722+ * collection containing elements that are not of the expected
1723+ * type
1724+ * @throws IOException
1725+ * if an I/O error occurs
1726+ * @throws SecurityException
1727+ * In the case of the default provider, and a security manager is
1728+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
1729+ * method denies write access to the file. If this method is invoked
1730+ * to set security sensitive attributes then the security manager
1731+ * may be invoked to check for additional permissions.
1732+ */
1733+ public static Path setAttribute(Path path, String attribute, Object value,
1734+ LinkOption... options)
1735+ throws IOException
1736+ {
1737+ provider(path).setAttribute(path, attribute, value, options);
1738+ return path;
1739+ }
1740+
1741+ /**
1742+ * Reads the value of a file attribute.
1743+ *
1744+ * <p> The {@code attribute} parameter identifies the attribute to be read
1745+ * and takes the form:
1746+ * <blockquote>
1747+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
1748+ * </blockquote>
1749+ * where square brackets [...] delineate an optional component and the
1750+ * character {@code ':'} stands for itself.
1751+ *
1752+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
1753+ * FileAttributeView} that identifies a set of file attributes. If not
1754+ * specified then it defaults to {@code "basic"}, the name of the file
1755+ * attribute view that identifies the basic set of file attributes common to
1756+ * many file systems. <i>attribute-name</i> is the name of the attribute.
1757+ *
1758+ * <p> The {@code options} array may be used to indicate how symbolic links
1759+ * are handled for the case that the file is a symbolic link. By default,
1760+ * symbolic links are followed and the file attribute of the final target
1761+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
1762+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
1763+ *
1764+ * <p> <b>Usage Example:</b>
1765+ * Suppose we require the user ID of the file owner on a system that
1766+ * supports a "{@code unix}" view:
1767+ * <pre>
1768+ * Path path = ...
1769+ * int uid = (Integer)Files.getAttribute(path, "unix:uid");
1770+ * </pre>
1771+ *
1772+ * @param path
1773+ * the path to the file
1774+ * @param attribute
1775+ * the attribute to read
1776+ * @param options
1777+ * options indicating how symbolic links are handled
1778+ *
1779+ * @return the attribute value
1780+ *
1781+ * @throws UnsupportedOperationException
1782+ * if the attribute view is not available
1783+ * @throws IllegalArgumentException
1784+ * if the attribute name is not specified or is not recognized
1785+ * @throws IOException
1786+ * if an I/O error occurs
1787+ * @throws SecurityException
1788+ * In the case of the default provider, and a security manager is
1789+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
1790+ * method denies read access to the file. If this method is invoked
1791+ * to read security sensitive attributes then the security manager
1792+ * may be invoked to check for additional permissions.
1793+ */
1794+ public static Object getAttribute(Path path, String attribute,
1795+ LinkOption... options)
1796+ throws IOException
1797+ {
1798+ // only one attribute should be read
1799+ if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
1800+ throw new IllegalArgumentException(attribute);
1801+ Map<String,Object> map = readAttributes(path, attribute, options);
1802+ assert map.size() == 1;
1803+ String name;
1804+ int pos = attribute.indexOf(':');
1805+ if (pos == -1) {
1806+ name = attribute;
1807+ } else {
1808+ name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
1809+ }
1810+ return map.get(name);
1811+ }
1812+
1813+ /**
1814+ * Reads a set of file attributes as a bulk operation.
1815+ *
1816+ * <p> The {@code attributes} parameter identifies the attributes to be read
1817+ * and takes the form:
1818+ * <blockquote>
1819+ * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
1820+ * </blockquote>
1821+ * where square brackets [...] delineate an optional component and the
1822+ * character {@code ':'} stands for itself.
1823+ *
1824+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
1825+ * FileAttributeView} that identifies a set of file attributes. If not
1826+ * specified then it defaults to {@code "basic"}, the name of the file
1827+ * attribute view that identifies the basic set of file attributes common to
1828+ * many file systems.
1829+ *
1830+ * <p> The <i>attribute-list</i> component is a comma separated list of
1831+ * zero or more names of attributes to read. If the list contains the value
1832+ * {@code "*"} then all attributes are read. Attributes that are not supported
1833+ * are ignored and will not be present in the returned map. It is
1834+ * implementation specific if all attributes are read as an atomic operation
1835+ * with respect to other file system operations.
1836+ *
1837+ * <p> The following examples demonstrate possible values for the {@code
1838+ * attributes} parameter:
1839+ *
1840+ * <blockquote>
1841+ * <table border="0">
1842+ * <tr>
1843+ * <td> {@code "*"} </td>
1844+ * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
1845+ * </tr>
1846+ * <tr>
1847+ * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
1848+ * <td> Reads the file size, last modified time, and last access time
1849+ * attributes. </td>
1850+ * </tr>
1851+ * <tr>
1852+ * <td> {@code "posix:*"} </td>
1853+ * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}. </td>
1854+ * </tr>
1855+ * <tr>
1856+ * <td> {@code "posix:permissions,owner,size"} </td>
1857+ * <td> Reads the POSX file permissions, owner, and file size. </td>
1858+ * </tr>
1859+ * </table>
1860+ * </blockquote>
1861+ *
1862+ * <p> The {@code options} array may be used to indicate how symbolic links
1863+ * are handled for the case that the file is a symbolic link. By default,
1864+ * symbolic links are followed and the file attribute of the final target
1865+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
1866+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
1867+ *
1868+ * @param path
1869+ * the path to the file
1870+ * @param attributes
1871+ * the attributes to read
1872+ * @param options
1873+ * options indicating how symbolic links are handled
1874+ *
1875+ * @return a map of the attributes returned; The map's keys are the
1876+ * attribute names, its values are the attribute values
1877+ *
1878+ * @throws UnsupportedOperationException
1879+ * if the attribute view is not available
1880+ * @throws IllegalArgumentException
1881+ * if no attributes are specified or an unrecognized attributes is
1882+ * specified
1883+ * @throws IOException
1884+ * if an I/O error occurs
1885+ * @throws SecurityException
1886+ * In the case of the default provider, and a security manager is
1887+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
1888+ * method denies read access to the file. If this method is invoked
1889+ * to read security sensitive attributes then the security manager
1890+ * may be invoke to check for additional permissions.
1891+ */
1892+ public static Map<String,Object> readAttributes(Path path, String attributes,
1893+ LinkOption... options)
1894+ throws IOException
1895+ {
1896+ return provider(path).readAttributes(path, attributes, options);
1897+ }
1898+
1899+ /**
1900+ * Returns a file's POSIX file permissions.
1901+ *
1902+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
1903+ * that supports the {@link PosixFileAttributeView}. This attribute view
1904+ * provides access to file attributes commonly associated with files on file
1905+ * systems used by operating systems that implement the Portable Operating
1906+ * System Interface (POSIX) family of standards.
1907+ *
1908+ * <p> The {@code options} array may be used to indicate how symbolic links
1909+ * are handled for the case that the file is a symbolic link. By default,
1910+ * symbolic links are followed and the file attribute of the final target
1911+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
1912+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
1913+ *
1914+ * @param path
1915+ * the path to the file
1916+ * @param options
1917+ * options indicating how symbolic links are handled
1918+ *
1919+ * @return the file permissions
1920+ *
1921+ * @throws UnsupportedOperationException
1922+ * if the associated file system does not support the {@code
1923+ * PosixFileAttributeView}
1924+ * @throws IOException
1925+ * if an I/O error occurs
1926+ * @throws SecurityException
1927+ * In the case of the default provider, a security manager is
1928+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
1929+ * or its {@link SecurityManager#checkRead(String) checkRead} method
1930+ * denies read access to the file.
1931+ */
1932+ public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
1933+ LinkOption... options)
1934+ throws IOException
1935+ {
1936+ return readAttributes(path, PosixFileAttributes.class, options).permissions();
1937+ }
1938+
1939+ /**
1940+ * Sets a file's POSIX permissions.
1941+ *
1942+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
1943+ * that supports the {@link PosixFileAttributeView}. This attribute view
1944+ * provides access to file attributes commonly associated with files on file
1945+ * systems used by operating systems that implement the Portable Operating
1946+ * System Interface (POSIX) family of standards.
1947+ *
1948+ * @param path
1949+ * A file reference that locates the file
1950+ * @param perms
1951+ * The new set of permissions
1952+ *
1953+ * @throws UnsupportedOperationException
1954+ * if the associated file system does not support the {@code
1955+ * PosixFileAttributeView}
1956+ * @throws ClassCastException
1957+ * if the sets contains elements that are not of type {@code
1958+ * PosixFilePermission}
1959+ * @throws IOException
1960+ * if an I/O error occurs
1961+ * @throws SecurityException
1962+ * In the case of the default provider, and a security manager is
1963+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
1964+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
1965+ * method denies write access to the file.
1966+ */
1967+ public static Path setPosixFilePermissions(Path path,
1968+ Set<PosixFilePermission> perms)
1969+ throws IOException
1970+ {
1971+ PosixFileAttributeView view =
1972+ getFileAttributeView(path, PosixFileAttributeView.class);
1973+ if (view == null)
1974+ throw new UnsupportedOperationException();
1975+ view.setPermissions(perms);
1976+ return path;
1977+ }
1978+
1979+ /**
1980+ * Returns the owner of a file.
1981+ *
1982+ * <p> The {@code path} parameter is associated with a file system that
1983+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
1984+ * access to a file attribute that is the owner of the file.
1985+ *
1986+ * @param path
1987+ * A file reference that locates the file
1988+ * @param options
1989+ * options indicating how symbolic links are handled
1990+ *
1991+ * @return A user principal representing the owner of the file
1992+ *
1993+ * @throws UnsupportedOperationException
1994+ * if the associated file system does not support the {@code
1995+ * FileOwnerAttributeView}
1996+ * @throws IOException
1997+ * if an I/O error occurs
1998+ * @throws SecurityException
1999+ * In the case of the default provider, and a security manager is
2000+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
2001+ * or its {@link SecurityManager#checkRead(String) checkRead} method
2002+ * denies read access to the file.
2003+ */
2004+ public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
2005+ FileOwnerAttributeView view =
2006+ getFileAttributeView(path, FileOwnerAttributeView.class, options);
2007+ if (view == null)
2008+ throw new UnsupportedOperationException();
2009+ return view.getOwner();
2010+ }
2011+
2012+ /**
2013+ * Updates the file owner.
2014+ *
2015+ * <p> The {@code path} parameter is associated with a file system that
2016+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
2017+ * access to a file attribute that is the owner of the file.
2018+ *
2019+ * <p> <b>Usage Example:</b>
2020+ * Suppose we want to make "joe" the owner of a file:
2021+ * <pre>
2022+ * Path path = ...
2023+ * UserPrincipalLookupService lookupService =
2024+ * provider(path).getUserPrincipalLookupService();
2025+ * UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
2026+ * Files.setOwner(path, joe);
2027+ * </pre>
2028+ *
2029+ * @param path
2030+ * A file reference that locates the file
2031+ * @param owner
2032+ * The new file owner
2033+ *
2034+ * @throws UnsupportedOperationException
2035+ * if the associated file system does not support the {@code
2036+ * FileOwnerAttributeView}
2037+ * @throws IOException
2038+ * if an I/O error occurs
2039+ * @throws SecurityException
2040+ * In the case of the default provider, and a security manager is
2041+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
2042+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
2043+ * method denies write access to the file.
2044+ *
2045+ * @see FileSystem#getUserPrincipalLookupService
2046+ * @see java.nio.file.attribute.UserPrincipalLookupService
2047+ */
2048+ public static Path setOwner(Path path, UserPrincipal owner)
2049+ throws IOException
2050+ {
2051+ FileOwnerAttributeView view =
2052+ getFileAttributeView(path, FileOwnerAttributeView.class);
2053+ if (view == null)
2054+ throw new UnsupportedOperationException();
2055+ view.setOwner(owner);
2056+ return path;
2057+ }
2058+
2059+ /**
2060+ * Tests whether a file is a symbolic link.
2061+ *
2062+ * <p> Where is it required to distinguish an I/O exception from the case
2063+ * that the file is not a symbolic link then the file attributes can be
2064+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
2065+ * readAttributes} method and the file type tested with the {@link
2066+ * BasicFileAttributes#isSymbolicLink} method.
2067+ *
2068+ * @return {@code true} if the file is a symbolic link; {@code false} if
2069+ * the file does not exist, is not a symbolic link, or it cannot
2070+ * be determined if the file is a symbolic link or not.
2071+ *
2072+ * @throws SecurityException
2073+ * In the case of the default provider, and a security manager is
2074+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
2075+ * method denies read access to the file.
2076+ */
2077+ public static boolean isSymbolicLink(Path path) {
2078+ try {
2079+ return readAttributes(path,
2080+ BasicFileAttributes.class,
2081+ LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
2082+ } catch (IOException ioe) {
2083+ return false;
2084+ }
2085+ }
2086+
2087+ /**
2088+ * Tests whether a file is a directory.
2089+ *
2090+ * <p> The {@code options} array may be used to indicate how symbolic links
2091+ * are handled for the case that the file is a symbolic link. By default,
2092+ * symbolic links are followed and the file attribute of the final target
2093+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
2094+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
2095+ *
2096+ * <p> Where is it required to distinguish an I/O exception from the case
2097+ * that the file is not a directory then the file attributes can be
2098+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
2099+ * readAttributes} method and the file type tested with the {@link
2100+ * BasicFileAttributes#isDirectory} method.
2101+ *
2102+ * @param path
2103+ * the path to the file to test
2104+ * @param options
2105+ * options indicating how symbolic links are handled
2106+ *
2107+ * @return {@code true} if the file is a directory; {@code false} if
2108+ * the file does not exist, is not a directory, or it cannot
2109+ * be determined if the file is a directory or not.
2110+ *
2111+ * @throws SecurityException
2112+ * In the case of the default provider, and a security manager is
2113+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
2114+ * method denies read access to the file.
2115+ */
2116+ public static boolean isDirectory(Path path, LinkOption... options) {
2117+ try {
2118+ return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
2119+ } catch (IOException ioe) {
2120+ return false;
2121+ }
2122+ }
2123+
2124+ /**
2125+ * Tests whether a file is a regular file with opaque content.
2126+ *
2127+ * <p> The {@code options} array may be used to indicate how symbolic links
2128+ * are handled for the case that the file is a symbolic link. By default,
2129+ * symbolic links are followed and the file attribute of the final target
2130+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
2131+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
2132+ *
2133+ * <p> Where is it required to distinguish an I/O exception from the case
2134+ * that the file is not a regular file then the file attributes can be
2135+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
2136+ * readAttributes} method and the file type tested with the {@link
2137+ * BasicFileAttributes#isRegularFile} method.
2138+ *
2139+ * @param path
2140+ * the path to the file
2141+ * @param options
2142+ * options indicating how symbolic links are handled
2143+ *
2144+ * @return {@code true} if the file is a regular file; {@code false} if
2145+ * the file does not exist, is not a regular file, or it
2146+ * cannot be determined if the file is a regular file or not.
2147+ *
2148+ * @throws SecurityException
2149+ * In the case of the default provider, and a security manager is
2150+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
2151+ * method denies read access to the file.
2152+ */
2153+ public static boolean isRegularFile(Path path, LinkOption... options) {
2154+ try {
2155+ return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
2156+ } catch (IOException ioe) {
2157+ return false;
2158+ }
2159+ }
2160+
2161+ /**
2162+ * Returns a file's last modified time.
2163+ *
2164+ * <p> The {@code options} array may be used to indicate how symbolic links
2165+ * are handled for the case that the file is a symbolic link. By default,
2166+ * symbolic links are followed and the file attribute of the final target
2167+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
2168+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
2169+ *
2170+ * @param path
2171+ * the path to the file
2172+ * @param options
2173+ * options indicating how symbolic links are handled
2174+ *
2175+ * @return a {@code FileTime} representing the time the file was last
2176+ * modified, or an implementation specific default when a time
2177+ * stamp to indicate the time of last modification is not supported
2178+ * by the file system
2179+ *
2180+ * @throws IOException
2181+ * if an I/O error occurs
2182+ * @throws SecurityException
2183+ * In the case of the default provider, and a security manager is
2184+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
2185+ * method denies read access to the file.
2186+ *
2187+ * @see BasicFileAttributes#lastModifiedTime
2188+ */
2189+ public static FileTime getLastModifiedTime(Path path, LinkOption... options)
2190+ throws IOException
2191+ {
2192+ return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
2193+ }
2194+
2195+ /**
2196+ * Updates a file's last modified time attribute. The file time is converted
2197+ * to the epoch and precision supported by the file system. Converting from
2198+ * finer to coarser granularities result in precision loss. The behavior of
2199+ * this method when attempting to set the last modified time when it is not
2200+ * supported by the file system or is outside the range supported by the
2201+ * underlying file store is not defined. It may or not fail by throwing an
2202+ * {@code IOException}.
2203+ *
2204+ * <p> <b>Usage Example:</b>
2205+ * Suppose we want to set the last modified time to the current time:
2206+ * <pre>
2207+ * Path path = ...
2208+ * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
2209+ * Files.setLastModifiedTime(path, now);
2210+ * </pre>
2211+ *
2212+ * @param path
2213+ * the path to the file
2214+ * @param time
2215+ * the new last modified time
2216+ *
2217+ * @return the file
2218+ *
2219+ * @throws IOException
2220+ * if an I/O error occurs
2221+ * @throws SecurityException
2222+ * In the case of the default provider, the security manager's {@link
2223+ * SecurityManager#checkWrite(String) checkWrite} method is invoked
2224+ * to check write access to file
2225+ *
2226+ * @see BasicFileAttributeView#setTimes
2227+ */
2228+ public static Path setLastModifiedTime(Path path, FileTime time)
2229+ throws IOException
2230+ {
2231+ getFileAttributeView(path, BasicFileAttributeView.class)
2232+ .setTimes(time, null, null);
2233+ return path;
2234+ }
2235+
2236+ /**
2237+ * Returns the size of a file (in bytes). The size may differ from the
2238+ * actual size on the file system due to compression, support for sparse
2239+ * files, or other reasons. The size of files that are not {@link
2240+ * #isRegularFile regular} files is implementation specific and
2241+ * therefore unspecified.
2242+ *
2243+ * @param path
2244+ * the path to the file
2245+ *
2246+ * @return the file size, in bytes
2247+ *
2248+ * @throws IOException
2249+ * if an I/O error occurs
2250+ * @throws SecurityException
2251+ * In the case of the default provider, and a security manager is
2252+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
2253+ * method denies read access to the file.
2254+ *
2255+ * @see BasicFileAttributes#size
2256+ */
2257+ public static long size(Path path) throws IOException {
2258+ return readAttributes(path, BasicFileAttributes.class).size();
2259+ }
2260+
2261+ // -- Accessibility --
2262+
2263+ /**
2264+ * Returns {@code false} if NOFOLLOW_LINKS is present.
2265+ */
2266+ private static boolean followLinks(LinkOption... options) {
2267+ boolean followLinks = true;
2268+ for (LinkOption opt: options) {
2269+ if (opt == LinkOption.NOFOLLOW_LINKS) {
2270+ followLinks = false;
2271+ continue;
2272+ }
2273+ if (opt == null)
2274+ throw new NullPointerException();
2275+ throw new AssertionError("Should not get here");
2276+ }
2277+ return followLinks;
2278+ }
2279+
2280+ /**
2281+ * Tests whether a file exists.
2282+ *
2283+ * <p> The {@code options} parameter may be used to indicate how symbolic links
2284+ * are handled for the case that the file is a symbolic link. By default,
2285+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
2286+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
2287+ *
2288+ * <p> Note that the result of this method is immediately outdated. If this
2289+ * method indicates the file exists then there is no guarantee that a
2290+ * subsequence access will succeed. Care should be taken when using this
2291+ * method in security sensitive applications.
2292+ *
2293+ * @param path
2294+ * the path to the file to test
2295+ * @param options
2296+ * options indicating how symbolic links are handled
2297+ * .
2298+ * @return {@code true} if the file exists; {@code false} if the file does
2299+ * not exist or its existence cannot be determined.
2300+ *
2301+ * @throws SecurityException
2302+ * In the case of the default provider, the {@link
2303+ * SecurityManager#checkRead(String)} is invoked to check
2304+ * read access to the file.
2305+ *
2306+ * @see #notExists
2307+ */
2308+ public static boolean exists(Path path, LinkOption... options) {
2309+ try {
2310+ if (followLinks(options)) {
2311+ provider(path).checkAccess(path);
2312+ } else {
2313+ // attempt to read attributes without following links
2314+ readAttributes(path, BasicFileAttributes.class,
2315+ LinkOption.NOFOLLOW_LINKS);
2316+ }
2317+ // file exists
2318+ return true;
2319+ } catch (IOException x) {
2320+ // does not exist or unable to determine if file exists
2321+ return false;
2322+ }
2323+
2324+ }
2325+
2326+ /**
2327+ * Tests whether the file located by this path does not exist. This method
2328+ * is intended for cases where it is required to take action when it can be
2329+ * confirmed that a file does not exist.
2330+ *
2331+ * <p> The {@code options} parameter may be used to indicate how symbolic links
2332+ * are handled for the case that the file is a symbolic link. By default,
2333+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
2334+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
2335+ *
2336+ * <p> Note that this method is not the complement of the {@link #exists
2337+ * exists} method. Where it is not possible to determine if a file exists
2338+ * or not then both methods return {@code false}. As with the {@code exists}
2339+ * method, the result of this method is immediately outdated. If this
2340+ * method indicates the file does exist then there is no guarantee that a
2341+ * subsequence attempt to create the file will succeed. Care should be taken
2342+ * when using this method in security sensitive applications.
2343+ *
2344+ * @param path
2345+ * the path to the file to test
2346+ * @param options
2347+ * options indicating how symbolic links are handled
2348+ *
2349+ * @return {@code true} if the file does not exist; {@code false} if the
2350+ * file exists or its existence cannot be determined
2351+ *
2352+ * @throws SecurityException
2353+ * In the case of the default provider, the {@link
2354+ * SecurityManager#checkRead(String)} is invoked to check
2355+ * read access to the file.
2356+ */
2357+ public static boolean notExists(Path path, LinkOption... options) {
2358+ try {
2359+ if (followLinks(options)) {
2360+ provider(path).checkAccess(path);
2361+ } else {
2362+ // attempt to read attributes without following links
2363+ readAttributes(path, BasicFileAttributes.class,
2364+ LinkOption.NOFOLLOW_LINKS);
2365+ }
2366+ // file exists
2367+ return false;
2368+ } catch (NoSuchFileException x) {
2369+ // file confirmed not to exist
2370+ return true;
2371+ } catch (IOException x) {
2372+ return false;
2373+ }
2374+ }
2375+
2376+ /**
2377+ * Used by isReadbale, isWritable, isExecutable to test access to a file.
2378+ */
2379+ private static boolean isAccessible(Path path, AccessMode... modes) {
2380+ try {
2381+ provider(path).checkAccess(path, modes);
2382+ return true;
2383+ } catch (IOException x) {
2384+ return false;
2385+ }
2386+ }
2387+
2388+ /**
2389+ * Tests whether a file is readable. This method checks that a file exists
2390+ * and that this Java virtual machine has appropriate privileges that would
2391+ * allow it open the file for reading. Depending on the implementation, this
2392+ * method may require to read file permissions, access control lists, or
2393+ * other file attributes in order to check the effective access to the file.
2394+ * Consequently, this method may not be atomic with respect to other file
2395+ * system operations.
2396+ *
2397+ * <p> Note that the result of this method is immediately outdated, there is
2398+ * no guarantee that a subsequent attempt to open the file for reading will
2399+ * succeed (or even that it will access the same file). Care should be taken
2400+ * when using this method in security sensitive applications.
2401+ *
2402+ * @param path
2403+ * the path to the file to check
2404+ *
2405+ * @return {@code true} if the file exists and is readable; {@code false}
2406+ * if the file does not exist, read access would be denied because
2407+ * the Java virtual machine has insufficient privileges, or access
2408+ * cannot be determined
2409+ *
2410+ * @throws SecurityException
2411+ * In the case of the default provider, and a security manager is
2412+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
2413+ * is invoked to check read access to the file.
2414+ */
2415+ public static boolean isReadable(Path path) {
2416+ return isAccessible(path, AccessMode.READ);
2417+ }
2418+
2419+ /**
2420+ * Tests whether a file is writable. This method checks that a file exists
2421+ * and that this Java virtual machine has appropriate privileges that would
2422+ * allow it open the file for writing. Depending on the implementation, this
2423+ * method may require to read file permissions, access control lists, or
2424+ * other file attributes in order to check the effective access to the file.
2425+ * Consequently, this method may not be atomic with respect to other file
2426+ * system operations.
2427+ *
2428+ * <p> Note that result of this method is immediately outdated, there is no
2429+ * guarantee that a subsequent attempt to open the file for writing will
2430+ * succeed (or even that it will access the same file). Care should be taken
2431+ * when using this method in security sensitive applications.
2432+ *
2433+ * @param path
2434+ * the path to the file to check
2435+ *
2436+ * @return {@code true} if the file exists and is writable; {@code false}
2437+ * if the file does not exist, write access would be denied because
2438+ * the Java virtual machine has insufficient privileges, or access
2439+ * cannot be determined
2440+ *
2441+ * @throws SecurityException
2442+ * In the case of the default provider, and a security manager is
2443+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
2444+ * is invoked to check write access to the file.
2445+ */
2446+ public static boolean isWritable(Path path) {
2447+ return isAccessible(path, AccessMode.WRITE);
2448+ }
2449+
2450+ /**
2451+ * Tests whether a file is executable. This method checks that a file exists
2452+ * and that this Java virtual machine has appropriate privileges to {@link
2453+ * Runtime#exec execute} the file. The semantics may differ when checking
2454+ * access to a directory. For example, on UNIX systems, checking for
2455+ * execute access checks that the Java virtual machine has permission to
2456+ * search the directory in order to access file or subdirectories.
2457+ *
2458+ * <p> Depending on the implementation, this method may require to read file
2459+ * permissions, access control lists, or other file attributes in order to
2460+ * check the effective access to the file. Consequently, this method may not
2461+ * be atomic with respect to other file system operations.
2462+ *
2463+ * <p> Note that the result of this method is immediately outdated, there is
2464+ * no guarantee that a subsequent attempt to execute the file will succeed
2465+ * (or even that it will access the same file). Care should be taken when
2466+ * using this method in security sensitive applications.
2467+ *
2468+ * @param path
2469+ * the path to the file to check
2470+ *
2471+ * @return {@code true} if the file exists and is executable; {@code false}
2472+ * if the file does not exist, execute access would be denied because
2473+ * the Java virtual machine has insufficient privileges, or access
2474+ * cannot be determined
2475+ *
2476+ * @throws SecurityException
2477+ * In the case of the default provider, and a security manager is
2478+ * installed, the {@link SecurityManager#checkExec(String)
2479+ * checkExec} is invoked to check execute access to the file.
2480+ */
2481+ public static boolean isExecutable(Path path) {
2482+ return isAccessible(path, AccessMode.EXECUTE);
2483+ }
2484+
2485+ // -- Recursive operations --
2486+
2487+ /**
2488+ * Walks a file tree.
2489+ *
2490+ * <p> This method walks a file tree rooted at a given starting file. The
2491+ * file tree traversal is <em>depth-first</em> with the given {@link
2492+ * FileVisitor} invoked for each file encountered. File tree traversal
2493+ * completes when all accessible files in the tree have been visited, or a
2494+ * visit method returns a result of {@link FileVisitResult#TERMINATE
2495+ * TERMINATE}. Where a visit method terminates due an {@code IOException},
2496+ * an uncaught error, or runtime exception, then the traversal is terminated
2497+ * and the error or exception is propagated to the caller of this method.
2498+ *
2499+ * <p> For each file encountered this method attempts to read its {@link
2500+ * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
2501+ * directory then the {@link FileVisitor#visitFile visitFile} method is
2502+ * invoked with the file attributes. If the file attributes cannot be read,
2503+ * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
2504+ * visitFileFailed} method is invoked with the I/O exception.
2505+ *
2506+ * <p> Where the file is a directory, and the directory could not be opened,
2507+ * then the {@code visitFileFailed} method is invoked with the I/O exception,
2508+ * after which, the file tree walk continues, by default, at the next
2509+ * <em>sibling</em> of the directory.
2510+ *
2511+ * <p> Where the directory is opened successfully, then the entries in the
2512+ * directory, and their <em>descendants</em> are visited. When all entries
2513+ * have been visited, or an I/O error occurs during iteration of the
2514+ * directory, then the directory is closed and the visitor's {@link
2515+ * FileVisitor#postVisitDirectory postVisitDirectory} method is invoked.
2516+ * The file tree walk then continues, by default, at the next <em>sibling</em>
2517+ * of the directory.
2518+ *
2519+ * <p> By default, symbolic links are not automatically followed by this
2520+ * method. If the {@code options} parameter contains the {@link
2521+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
2522+ * followed. When following links, and the attributes of the target cannot
2523+ * be read, then this method attempts to get the {@code BasicFileAttributes}
2524+ * of the link. If they can be read then the {@code visitFile} method is
2525+ * invoked with the attributes of the link (otherwise the {@code visitFileFailed}
2526+ * method is invoked as specified above).
2527+ *
2528+ * <p> If the {@code options} parameter contains the {@link
2529+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
2530+ * track of directories visited so that cycles can be detected. A cycle
2531+ * arises when there is an entry in a directory that is an ancestor of the
2532+ * directory. Cycle detection is done by recording the {@link
2533+ * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
2534+ * or if file keys are not available, by invoking the {@link #isSameFile
2535+ * isSameFile} method to test if a directory is the same file as an
2536+ * ancestor. When a cycle is detected it is treated as an I/O error, and the
2537+ * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
2538+ * an instance of {@link FileSystemLoopException}.
2539+ *
2540+ * <p> The {@code maxDepth} parameter is the maximum number of levels of
2541+ * directories to visit. A value of {@code 0} means that only the starting
2542+ * file is visited, unless denied by the security manager. A value of
2543+ * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
2544+ * levels should be visited. The {@code visitFile} method is invoked for all
2545+ * files, including directories, encountered at {@code maxDepth}, unless the
2546+ * basic file attributes cannot be read, in which case the {@code
2547+ * visitFileFailed} method is invoked.
2548+ *
2549+ * <p> If a visitor returns a result of {@code null} then {@code
2550+ * NullPointerException} is thrown.
2551+ *
2552+ * <p> When a security manager is installed and it denies access to a file
2553+ * (or directory), then it is ignored and the visitor is not invoked for
2554+ * that file (or directory).
2555+ *
2556+ * @param start
2557+ * the starting file
2558+ * @param options
2559+ * options to configure the traversal
2560+ * @param maxDepth
2561+ * the maximum number of directory levels to visit
2562+ * @param visitor
2563+ * the file visitor to invoke for each file
2564+ *
2565+ * @return the starting file
2566+ *
2567+ * @throws IllegalArgumentException
2568+ * if the {@code maxDepth} parameter is negative
2569+ * @throws SecurityException
2570+ * If the security manager denies access to the starting file.
2571+ * In the case of the default provider, the {@link
2572+ * SecurityManager#checkRead(String) checkRead} method is invoked
2573+ * to check read access to the directory.
2574+ * @throws IOException
2575+ * if an I/O error is thrown by a visitor method
2576+ */
2577+ public static Path walkFileTree(Path start,
2578+ Set<FileVisitOption> options,
2579+ int maxDepth,
2580+ FileVisitor<? super Path> visitor)
2581+ throws IOException
2582+ {
2583+ if (maxDepth < 0)
2584+ throw new IllegalArgumentException("'maxDepth' is negative");
2585+ new FileTreeWalker(options, visitor, maxDepth).walk(start);
2586+ return start;
2587+ }
2588+
2589+ /**
2590+ * Walks a file tree.
2591+ *
2592+ * <p> This method works as if invoking it were equivalent to evaluating the
2593+ * expression:
2594+ * <blockquote><pre>
2595+ * walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
2596+ * </pre></blockquote>
2597+ * In other words, it does not follow symbolic links, and visits all levels
2598+ * of the file tree.
2599+ *
2600+ * @param start
2601+ * the starting file
2602+ * @param visitor
2603+ * the file visitor to invoke for each file
2604+ *
2605+ * @return the starting file
2606+ *
2607+ * @throws SecurityException
2608+ * If the security manager denies access to the starting file.
2609+ * In the case of the default provider, the {@link
2610+ * SecurityManager#checkRead(String) checkRead} method is invoked
2611+ * to check read access to the directory.
2612+ * @throws IOException
2613+ * if an I/O error is thrown by a visitor method
2614+ */
2615+ public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
2616+ throws IOException
2617+ {
2618+ return walkFileTree(start,
2619+ EnumSet.noneOf(FileVisitOption.class),
2620+ Integer.MAX_VALUE,
2621+ visitor);
2622+ }
2623+
2624+
2625+ // -- Utility methods for simple usages --
2626+
2627+ // buffer size used for reading and writing
2628+ private static final int BUFFER_SIZE = 8192;
2629+
2630+ /**
2631+ * Opens a file for reading, returning a {@code BufferedReader} that may be
2632+ * used to read text from the file in an efficient manner. Bytes from the
2633+ * file are decoded into characters using the specified charset. Reading
2634+ * commences at the beginning of the file.
2635+ *
2636+ * <p> The {@code Reader} methods that read from the file throw {@code
2637+ * IOException} if a malformed or unmappable byte sequence is read.
2638+ *
2639+ * @param path
2640+ * the path to the file
2641+ * @param cs
2642+ * the charset to use for decoding
2643+ *
2644+ * @return a new buffered reader, with default buffer size, to read text
2645+ * from the file
2646+ *
2647+ * @throws IOException
2648+ * if an I/O error occurs opening the file
2649+ * @throws SecurityException
2650+ * In the case of the default provider, and a security manager is
2651+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
2652+ * method is invoked to check read access to the file.
2653+ *
2654+ * @see #readAllLines
2655+ */
2656+ public static BufferedReader newBufferedReader(Path path, Charset cs)
2657+ throws IOException
2658+ {
2659+ CharsetDecoder decoder = cs.newDecoder();
2660+ Reader reader = new InputStreamReader(newInputStream(path), decoder);
2661+ return new BufferedReader(reader);
2662+ }
2663+
2664+ /**
2665+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
2666+ * that may be used to write text to the file in an efficient manner.
2667+ * The {@code options} parameter specifies how the the file is created or
2668+ * opened. If no options are present then this method works as if the {@link
2669+ * StandardOpenOption#CREATE CREATE}, {@link
2670+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
2671+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
2672+ * opens the file for writing, creating the file if it doesn't exist, or
2673+ * initially truncating an existing {@link #isRegularFile regular-file} to
2674+ * a size of {@code 0} if it exists.
2675+ *
2676+ * <p> The {@code Writer} methods to write text throw {@code IOException}
2677+ * if the text cannot be encoded using the specified charset.
2678+ *
2679+ * @param path
2680+ * the path to the file
2681+ * @param cs
2682+ * the charset to use for encoding
2683+ * @param options
2684+ * options specifying how the file is opened
2685+ *
2686+ * @return a new buffered writer, with default buffer size, to write text
2687+ * to the file
2688+ *
2689+ * @throws IOException
2690+ * if an I/O error occurs opening or creating the file
2691+ * @throws UnsupportedOperationException
2692+ * if an unsupported option is specified
2693+ * @throws SecurityException
2694+ * In the case of the default provider, and a security manager is
2695+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
2696+ * method is invoked to check write access to the file.
2697+ *
2698+ * @see #write(Path,Iterable,Charset,OpenOption[])
2699+ */
2700+ public static BufferedWriter newBufferedWriter(Path path, Charset cs,
2701+ OpenOption... options)
2702+ throws IOException
2703+ {
2704+ CharsetEncoder encoder = cs.newEncoder();
2705+ Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
2706+ return new BufferedWriter(writer);
2707+ }
2708+
2709+ /**
2710+ * Reads all bytes from an input stream and writes them to an output stream.
2711+ */
2712+ private static long copy(InputStream source, OutputStream sink)
2713+ throws IOException
2714+ {
2715+ long nread = 0L;
2716+ byte[] buf = new byte[BUFFER_SIZE];
2717+ int n;
2718+ while ((n = source.read(buf)) > 0) {
2719+ sink.write(buf, 0, n);
2720+ nread += n;
2721+ }
2722+ return nread;
2723+ }
2724+
2725+ /**
2726+ * Copies all bytes from an input stream to a file. On return, the input
2727+ * stream will be at end of stream.
2728+ *
2729+ * <p> By default, the copy fails if the target file already exists or is a
2730+ * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
2731+ * REPLACE_EXISTING} option is specified, and the target file already exists,
2732+ * then it is replaced if it is not a non-empty directory. If the target
2733+ * file exists and is a symbolic link, then the symbolic link is replaced.
2734+ * In this release, the {@code REPLACE_EXISTING} option is the only option
2735+ * required to be supported by this method. Additional options may be
2736+ * supported in future releases.
2737+ *
2738+ * <p> If an I/O error occurs reading from the input stream or writing to
2739+ * the file, then it may do so after the target file has been created and
2740+ * after some bytes have been read or written. Consequently the input
2741+ * stream may not be at end of stream and may be in an inconsistent state.
2742+ * It is strongly recommended that the input stream be promptly closed if an
2743+ * I/O error occurs.
2744+ *
2745+ * <p> This method may block indefinitely reading from the input stream (or
2746+ * writing to the file). The behavior for the case that the input stream is
2747+ * <i>asynchronously closed</i> or the thread interrupted during the copy is
2748+ * highly input stream and file system provider specific and therefore not
2749+ * specified.
2750+ *
2751+ * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
2752+ * it to a file:
2753+ * <pre>
2754+ * Path path = ...
2755+ * URI u = URI.create("http://java.sun.com/");
2756+ * try (InputStream in = u.toURL().openStream()) {
2757+ * Files.copy(in, path);
2758+ * }
2759+ * </pre>
2760+ *
2761+ * @param in
2762+ * the input stream to read from
2763+ * @param target
2764+ * the path to the file
2765+ * @param options
2766+ * options specifying how the copy should be done
2767+ *
2768+ * @return the number of bytes read or written
2769+ *
2770+ * @throws IOException
2771+ * if an I/O error occurs when reading or writing
2772+ * @throws FileAlreadyExistsException
2773+ * if the target file exists but cannot be replaced because the
2774+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
2775+ * specific exception)</i>
2776+ * @throws DirectoryNotEmptyException
2777+ * the {@code REPLACE_EXISTING} option is specified but the file
2778+ * cannot be replaced because it is a non-empty directory
2779+ * <i>(optional specific exception)</i> *
2780+ * @throws UnsupportedOperationException
2781+ * if {@code options} contains a copy option that is not supported
2782+ * @throws SecurityException
2783+ * In the case of the default provider, and a security manager is
2784+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
2785+ * method is invoked to check write access to the file. Where the
2786+ * {@code REPLACE_EXISTING} option is specified, the security
2787+ * manager's {@link SecurityManager#checkDelete(String) checkDelete}
2788+ * method is invoked to check that an existing file can be deleted.
2789+ */
2790+ public static long copy(InputStream in, Path target, CopyOption... options)
2791+ throws IOException
2792+ {
2793+ // ensure not null before opening file
2794+ Objects.requireNonNull(in);
2795+
2796+ // check for REPLACE_EXISTING
2797+ boolean replaceExisting = false;
2798+ for (CopyOption opt: options) {
2799+ if (opt == StandardCopyOption.REPLACE_EXISTING) {
2800+ replaceExisting = true;
2801+ } else {
2802+ if (opt == null) {
2803+ throw new NullPointerException("options contains 'null'");
2804+ } else {
2805+ throw new UnsupportedOperationException(opt + " not supported");
2806+ }
2807+ }
2808+ }
2809+
2810+ // attempt to delete an existing file
2811+ SecurityException se = null;
2812+ if (replaceExisting) {
2813+ try {
2814+ deleteIfExists(target);
2815+ } catch (SecurityException x) {
2816+ se = x;
2817+ }
2818+ }
2819+
2820+ // attempt to create target file. If it fails with
2821+ // FileAlreadyExistsException then it may be because the security
2822+ // manager prevented us from deleting the file, in which case we just
2823+ // throw the SecurityException.
2824+ OutputStream ostream;
2825+ try {
2826+ ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
2827+ StandardOpenOption.WRITE);
2828+ } catch (FileAlreadyExistsException x) {
2829+ if (se != null)
2830+ throw se;
2831+ // someone else won the race and created the file
2832+ throw x;
2833+ }
2834+
2835+ // do the copy
2836+ try (OutputStream out = ostream) {
2837+ return copy(in, out);
2838+ }
2839+ }
2840+
2841+ /**
2842+ * Copies all bytes from a file to an output stream.
2843+ *
2844+ * <p> If an I/O error occurs reading from the file or writing to the output
2845+ * stream, then it may do so after some bytes have been read or written.
2846+ * Consequently the output stream may be in an inconsistent state. It is
2847+ * strongly recommended that the output stream be promptly closed if an I/O
2848+ * error occurs.
2849+ *
2850+ * <p> This method may block indefinitely writing to the output stream (or
2851+ * reading from the file). The behavior for the case that the output stream
2852+ * is <i>asynchronously closed</i> or the thread interrupted during the copy
2853+ * is highly output stream and file system provider specific and therefore
2854+ * not specified.
2855+ *
2856+ * <p> Note that if the given output stream is {@link java.io.Flushable}
2857+ * then its {@link java.io.Flushable#flush flush} method may need to invoked
2858+ * after this method completes so as to flush any buffered output.
2859+ *
2860+ * @param source
2861+ * the path to the file
2862+ * @param out
2863+ * the output stream to write to
2864+ *
2865+ * @return the number of bytes read or written
2866+ *
2867+ * @throws IOException
2868+ * if an I/O error occurs when reading or writing
2869+ * @throws SecurityException
2870+ * In the case of the default provider, and a security manager is
2871+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
2872+ * method is invoked to check read access to the file.
2873+ */
2874+ public static long copy(Path source, OutputStream out) throws IOException {
2875+ // ensure not null before opening file
2876+ Objects.requireNonNull(out);
2877+
2878+ try (InputStream in = newInputStream(source)) {
2879+ return copy(in, out);
2880+ }
2881+ }
2882+
2883+ /**
2884+ * Read all the bytes from an input stream. The {@code initialSize}
2885+ * parameter indicates the initial size of the byte[] to allocate.
2886+ */
2887+ private static byte[] read(InputStream source, int initialSize)
2888+ throws IOException
2889+ {
2890+ int capacity = initialSize;
2891+ byte[] buf = new byte[capacity];
2892+ int nread = 0;
2893+ int rem = buf.length;
2894+ int n;
2895+ // read to EOF which may read more or less than initialSize (eg: file
2896+ // is truncated while we are reading)
2897+ while ((n = source.read(buf, nread, rem)) > 0) {
2898+ nread += n;
2899+ rem -= n;
2900+ assert rem >= 0;
2901+ if (rem == 0) {
2902+ // need larger buffer
2903+ int newCapacity = capacity << 1;
2904+ if (newCapacity < 0) {
2905+ if (capacity == Integer.MAX_VALUE)
2906+ throw new OutOfMemoryError("Required array size too large");
2907+ newCapacity = Integer.MAX_VALUE;
2908+ }
2909+ rem = newCapacity - capacity;
2910+ buf = Arrays.copyOf(buf, newCapacity);
2911+ capacity = newCapacity;
2912+ }
2913+ }
2914+ return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
2915+ }
2916+
2917+ /**
2918+ * Read all the bytes from a file. The method ensures that the file is
2919+ * closed when all bytes have been read or an I/O error, or other runtime
2920+ * exception, is thrown.
2921+ *
2922+ * <p> Note that this method is intended for simple cases where it is
2923+ * convenient to read all bytes into a byte array. It is not intended for
2924+ * reading in large files.
2925+ *
2926+ * @param path
2927+ * the path to the file
2928+ *
2929+ * @return a byte array containing the bytes read from the file
2930+ *
2931+ * @throws IOException
2932+ * if an I/O error occurs reading from the stream
2933+ * @throws OutOfMemoryError
2934+ * if an array of the required size cannot be allocated, for
2935+ * example the file is larger that {@code 2GB}
2936+ * @throws SecurityException
2937+ * In the case of the default provider, and a security manager is
2938+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
2939+ * method is invoked to check read access to the file.
2940+ */
2941+ public static byte[] readAllBytes(Path path) throws IOException {
2942+ long size = size(path);
2943+ if (size > (long)Integer.MAX_VALUE)
2944+ throw new OutOfMemoryError("Required array size too large");
2945+
2946+ try (InputStream in = newInputStream(path)) {
2947+ return read(in, (int)size);
2948+ }
2949+ }
2950+
2951+ /**
2952+ * Read all lines from a file. This method ensures that the file is
2953+ * closed when all bytes have been read or an I/O error, or other runtime
2954+ * exception, is thrown. Bytes from the file are decoded into characters
2955+ * using the specified charset.
2956+ *
2957+ * <p> This method recognizes the following as line terminators:
2958+ * <ul>
2959+ * <li> <code>&#92;u000D</code> followed by <code>&#92;u000A</code>,
2960+ * CARRIAGE RETURN followed by LINE FEED </li>
2961+ * <li> <code>&#92;u000A</code>, LINE FEED </li>
2962+ * <li> <code>&#92;u000D</code>, CARRIAGE RETURN </li>
2963+ * </ul>
2964+ * <p> Additional Unicode line terminators may be recognized in future
2965+ * releases.
2966+ *
2967+ * <p> Note that this method is intended for simple cases where it is
2968+ * convenient to read all lines in a single operation. It is not intended
2969+ * for reading in large files.
2970+ *
2971+ * @param path
2972+ * the path to the file
2973+ * @param cs
2974+ * the charset to use for decoding
2975+ *
2976+ * @return the lines from the file as a {@code List}; whether the {@code
2977+ * List} is modifiable or not is implementation dependent and
2978+ * therefore not specified
2979+ *
2980+ * @throws IOException
2981+ * if an I/O error occurs reading from the file or a malformed or
2982+ * unmappable byte sequence is read
2983+ * @throws SecurityException
2984+ * In the case of the default provider, and a security manager is
2985+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
2986+ * method is invoked to check read access to the file.
2987+ *
2988+ * @see #newBufferedReader
2989+ */
2990+ public static List<String> readAllLines(Path path, Charset cs)
2991+ throws IOException
2992+ {
2993+ try (BufferedReader reader = newBufferedReader(path, cs)) {
2994+ List<String> result = new ArrayList<>();
2995+ for (;;) {
2996+ String line = reader.readLine();
2997+ if (line == null)
2998+ break;
2999+ result.add(line);
3000+ }
3001+ return result;
3002+ }
3003+ }
3004+
3005+ /**
3006+ * Writes bytes to a file. The {@code options} parameter specifies how the
3007+ * the file is created or opened. If no options are present then this method
3008+ * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
3009+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
3010+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
3011+ * opens the file for writing, creating the file if it doesn't exist, or
3012+ * initially truncating an existing {@link #isRegularFile regular-file} to
3013+ * a size of {@code 0}. All bytes in the byte array are written to the file.
3014+ * The method ensures that the file is closed when all bytes have been
3015+ * written (or an I/O error or other runtime exception is thrown). If an I/O
3016+ * error occurs then it may do so after the file has created or truncated,
3017+ * or after some bytes have been written to the file.
3018+ *
3019+ * <p> <b>Usage example</b>: By default the method creates a new file or
3020+ * overwrites an existing file. Suppose you instead want to append bytes
3021+ * to an existing file:
3022+ * <pre>
3023+ * Path path = ...
3024+ * byte[] bytes = ...
3025+ * Files.write(path, bytes, StandardOpenOption.APPEND);
3026+ * </pre>
3027+ *
3028+ * @param path
3029+ * the path to the file
3030+ * @param bytes
3031+ * the byte array with the bytes to write
3032+ * @param options
3033+ * options specifying how the file is opened
3034+ *
3035+ * @return the path
3036+ *
3037+ * @throws IOException
3038+ * if an I/O error occurs writing to or creating the file
3039+ * @throws UnsupportedOperationException
3040+ * if an unsupported option is specified
3041+ * @throws SecurityException
3042+ * In the case of the default provider, and a security manager is
3043+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
3044+ * method is invoked to check write access to the file.
3045+ */
3046+ public static Path write(Path path, byte[] bytes, OpenOption... options)
3047+ throws IOException
3048+ {
3049+ // ensure bytes is not null before opening file
3050+ Objects.requireNonNull(bytes);
3051+
3052+ try (OutputStream out = Files.newOutputStream(path, options)) {
3053+ int len = bytes.length;
3054+ int rem = len;
3055+ while (rem > 0) {
3056+ int n = Math.min(rem, BUFFER_SIZE);
3057+ out.write(bytes, (len-rem), n);
3058+ rem -= n;
3059+ }
3060+ }
3061+ return path;
3062+ }
3063+
3064+ /**
3065+ * Write lines of text to a file. Each line is a char sequence and is
3066+ * written to the file in sequence with each line terminated by the
3067+ * platform's line separator, as defined by the system property {@code
3068+ * line.separator}. Characters are encoded into bytes using the specified
3069+ * charset.
3070+ *
3071+ * <p> The {@code options} parameter specifies how the the file is created
3072+ * or opened. If no options are present then this method works as if the
3073+ * {@link StandardOpenOption#CREATE CREATE}, {@link
3074+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
3075+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
3076+ * opens the file for writing, creating the file if it doesn't exist, or
3077+ * initially truncating an existing {@link #isRegularFile regular-file} to
3078+ * a size of {@code 0}. The method ensures that the file is closed when all
3079+ * lines have been written (or an I/O error or other runtime exception is
3080+ * thrown). If an I/O error occurs then it may do so after the file has
3081+ * created or truncated, or after some bytes have been written to the file.
3082+ *
3083+ * @param path
3084+ * the path to the file
3085+ * @param lines
3086+ * an object to iterate over the char sequences
3087+ * @param cs
3088+ * the charset to use for encoding
3089+ * @param options
3090+ * options specifying how the file is opened
3091+ *
3092+ * @return the path
3093+ *
3094+ * @throws IOException
3095+ * if an I/O error occurs writing to or creating the file, or the
3096+ * text cannot be encoded using the specified charset
3097+ * @throws UnsupportedOperationException
3098+ * if an unsupported option is specified
3099+ * @throws SecurityException
3100+ * In the case of the default provider, and a security manager is
3101+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
3102+ * method is invoked to check write access to the file.
3103+ */
3104+ public static Path write(Path path, Iterable<? extends CharSequence> lines,
3105+ Charset cs, OpenOption... options)
3106+ throws IOException
3107+ {
3108+ // ensure lines is not null before opening file
3109+ Objects.requireNonNull(lines);
3110+ CharsetEncoder encoder = cs.newEncoder();
3111+ OutputStream out = newOutputStream(path, options);
3112+ try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
3113+ for (CharSequence line: lines) {
3114+ writer.append(line);
3115+ writer.newLine();
3116+ }
3117+ }
3118+ return path;
3119+ }
3120+}