1 /*
   2  * Copyright (c) 2007, 2018, 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.spi;
  27 
  28 import java.nio.channels.AsynchronousFileChannel;
  29 import java.nio.channels.Channels;
  30 import java.nio.channels.FileChannel;
  31 import java.nio.channels.ReadableByteChannel;
  32 import java.nio.channels.SeekableByteChannel;
  33 import java.nio.channels.WritableByteChannel;
  34 import java.nio.file.AccessDeniedException;
  35 import java.nio.file.AccessMode;
  36 import java.nio.file.AtomicMoveNotSupportedException;
  37 import java.nio.file.CopyOption;
  38 import java.nio.file.DirectoryNotEmptyException;
  39 import java.nio.file.DirectoryStream;
  40 import java.nio.file.FileAlreadyExistsException;
  41 import java.nio.file.FileStore;
  42 import java.nio.file.FileSystem;
  43 import java.nio.file.FileSystemAlreadyExistsException;
  44 import java.nio.file.FileSystemNotFoundException;
  45 import java.nio.file.FileSystems;
  46 import java.nio.file.Files;
  47 import java.nio.file.LinkOption;
  48 import java.nio.file.LinkPermission;
  49 import java.nio.file.NoSuchFileException;
  50 import java.nio.file.NotDirectoryException;
  51 import java.nio.file.NotLinkException;
  52 import java.nio.file.OpenOption;
  53 import java.nio.file.Path;
  54 import java.nio.file.StandardOpenOption;
  55 import java.net.URI;
  56 import java.io.InputStream;
  57 import java.io.OutputStream;
  58 import java.io.IOException;
  59 import java.nio.file.attribute.BasicFileAttributes;
  60 import java.nio.file.attribute.FileAttribute;
  61 import java.nio.file.attribute.FileAttributeView;
  62 import java.util.ArrayList;
  63 import java.util.Collections;
  64 import java.util.HashSet;
  65 import java.util.List;
  66 import java.util.Map;
  67 import java.util.ServiceConfigurationError;
  68 import java.util.ServiceLoader;
  69 import java.util.Set;
  70 import java.util.concurrent.ExecutorService;
  71 import java.security.AccessController;
  72 import java.security.PrivilegedAction;
  73 
  74 import sun.nio.ch.FileChannelImpl;
  75 
  76 /**
  77  * Service-provider class for file systems. The methods defined by the {@link
  78  * java.nio.file.Files} class will typically delegate to an instance of this
  79  * class.
  80  *
  81  * <p> A file system provider is a concrete implementation of this class that
  82  * implements the abstract methods defined by this class. A provider is
  83  * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
  84  * is identified by the URI scheme "file". It creates the {@link FileSystem} that
  85  * provides access to the file systems accessible to the Java virtual machine.
  86  * The {@link FileSystems} class defines how file system providers are located
  87  * and loaded. The default provider is typically a system-default provider but
  88  * may be overridden if the system property {@code
  89  * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
  90  * provider has a one argument constructor whose formal parameter type is {@code
  91  * FileSystemProvider}. All other providers have a zero argument constructor
  92  * that initializes the provider.
  93  *
  94  * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
  95  * file system is identified by a {@code URI} where the URI's scheme matches
  96  * the provider's {@link #getScheme scheme}. The default file system, for example,
  97  * is identified by the URI {@code "file:///"}. A memory-based file system,
  98  * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
  99  * The {@link #newFileSystem newFileSystem} method may be used to create a file
 100  * system, and the {@link #getFileSystem getFileSystem} method may be used to
 101  * obtain a reference to an existing file system created by the provider. Where
 102  * a provider is the factory for a single file system then it is provider dependent
 103  * if the file system is created when the provider is initialized, or later when
 104  * the {@code newFileSystem} method is invoked. In the case of the system-default
 105  * provider, the {@code FileSystem} is created when the provider is initialized.
 106  *
 107  * <p> All of the methods in this class are safe for use by multiple concurrent
 108  * threads.
 109  *
 110  * @since 1.7
 111  */
 112 
 113 public abstract class FileSystemProvider {
 114     // lock using when loading providers
 115     private static final Object lock = new Object();
 116 
 117     // installed providers
 118     private static volatile List<FileSystemProvider> installedProviders;
 119 
 120     // used to avoid recursive loading of installed providers
 121     private static boolean loadingProviders  = false;
 122 
 123     private static Void checkPermission() {
 124         SecurityManager sm = System.getSecurityManager();
 125         if (sm != null)
 126             sm.checkPermission(new RuntimePermission("fileSystemProvider"));
 127         return null;
 128     }
 129     private FileSystemProvider(Void ignore) { }
 130 
 131     /**
 132      * Initializes a new instance of this class.
 133      *
 134      * <p> During construction a provider may safely access files associated
 135      * with the default provider but care needs to be taken to avoid circular
 136      * loading of other installed providers. If circular loading of installed
 137      * providers is detected then an unspecified error is thrown.
 138      *
 139      * @throws  SecurityException
 140      *          If a security manager has been installed and it denies
 141      *          {@link RuntimePermission}{@code ("fileSystemProvider")}
 142      */
 143     protected FileSystemProvider() {
 144         this(checkPermission());
 145     }
 146 
 147     // loads all installed providers
 148     private static List<FileSystemProvider> loadInstalledProviders() {
 149         List<FileSystemProvider> list = new ArrayList<>();
 150 
 151         ServiceLoader<FileSystemProvider> sl = ServiceLoader
 152             .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
 153 
 154         // ServiceConfigurationError may be throw here
 155         for (FileSystemProvider provider: sl) {
 156             String scheme = provider.getScheme();
 157 
 158             // add to list if the provider is not "file" and isn't a duplicate
 159             if (!scheme.equalsIgnoreCase("file")) {
 160                 boolean found = false;
 161                 for (FileSystemProvider p: list) {
 162                     if (p.getScheme().equalsIgnoreCase(scheme)) {
 163                         found = true;
 164                         break;
 165                     }
 166                 }
 167                 if (!found) {
 168                     list.add(provider);
 169                 }
 170             }
 171         }
 172         return list;
 173     }
 174 
 175     /**
 176      * Returns a list of the installed file system providers.
 177      *
 178      * <p> The first invocation of this method causes the default provider to be
 179      * initialized (if not already initialized) and loads any other installed
 180      * providers as described by the {@link FileSystems} class.
 181      *
 182      * @return  An unmodifiable list of the installed file system providers. The
 183      *          list contains at least one element, that is the default file
 184      *          system provider
 185      *
 186      * @throws  ServiceConfigurationError
 187      *          When an error occurs while loading a service provider
 188      */
 189     public static List<FileSystemProvider> installedProviders() {
 190         if (installedProviders == null) {
 191             // ensure default provider is initialized
 192             FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
 193 
 194             synchronized (lock) {
 195                 if (installedProviders == null) {
 196                     if (loadingProviders) {
 197                         throw new Error("Circular loading of installed providers detected");
 198                     }
 199                     loadingProviders = true;
 200 
 201                     List<FileSystemProvider> list = AccessController
 202                         .doPrivileged(new PrivilegedAction<>() {
 203                             @Override
 204                             public List<FileSystemProvider> run() {
 205                                 return loadInstalledProviders();
 206                         }});
 207 
 208                     // insert the default provider at the start of the list
 209                     list.add(0, defaultProvider);
 210 
 211                     installedProviders = Collections.unmodifiableList(list);
 212                 }
 213             }
 214         }
 215         return installedProviders;
 216     }
 217 
 218     /**
 219      * Returns the URI scheme that identifies this provider.
 220      *
 221      * @return  The URI scheme
 222      */
 223     public abstract String getScheme();
 224 
 225     /**
 226      * Constructs a new {@code FileSystem} object identified by a URI. This
 227      * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
 228      * method to open a new file system identified by a URI.
 229      *
 230      * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
 231      * scheme equal (without regard to case) to the scheme supported by this
 232      * provider. The exact form of the URI is highly provider dependent. The
 233      * {@code env} parameter is a map of provider specific properties to configure
 234      * the file system.
 235      *
 236      * <p> This method throws {@link FileSystemAlreadyExistsException} if the
 237      * file system already exists because it was previously created by an
 238      * invocation of this method. Once a file system is {@link
 239      * java.nio.file.FileSystem#close closed} it is provider-dependent if the
 240      * provider allows a new file system to be created with the same URI as a
 241      * file system it previously created.
 242      *
 243      * @param   uri
 244      *          URI reference
 245      * @param   env
 246      *          A map of provider specific properties to configure the file system;
 247      *          may be empty
 248      *
 249      * @return  A new file system
 250      *
 251      * @throws  IllegalArgumentException
 252      *          If the pre-conditions for the {@code uri} parameter aren't met,
 253      *          or the {@code env} parameter does not contain properties required
 254      *          by the provider, or a property value is invalid
 255      * @throws  IOException
 256      *          An I/O error occurs creating the file system
 257      * @throws  SecurityException
 258      *          If a security manager is installed and it denies an unspecified
 259      *          permission required by the file system provider implementation
 260      * @throws  FileSystemAlreadyExistsException
 261      *          If the file system has already been created
 262      */
 263     public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
 264         throws IOException;
 265 
 266     /**
 267      * Returns an existing {@code FileSystem} created by this provider.
 268      *
 269      * <p> This method returns a reference to a {@code FileSystem} that was
 270      * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
 271      * method. File systems created the {@link #newFileSystem(Path,Map)
 272      * newFileSystem(Path,Map)} method are not returned by this method.
 273      * The file system is identified by its {@code URI}. Its exact form
 274      * is highly provider dependent. In the case of the default provider the URI's
 275      * path component is {@code "/"} and the authority, query and fragment components
 276      * are undefined (Undefined components are represented by {@code null}).
 277      *
 278      * <p> Once a file system created by this provider is {@link
 279      * java.nio.file.FileSystem#close closed} it is provider-dependent if this
 280      * method returns a reference to the closed file system or throws {@link
 281      * FileSystemNotFoundException}. If the provider allows a new file system to
 282      * be created with the same URI as a file system it previously created then
 283      * this method throws the exception if invoked after the file system is
 284      * closed (and before a new instance is created by the {@link #newFileSystem
 285      * newFileSystem} method).
 286      *
 287      * <p> If a security manager is installed then a provider implementation
 288      * may require to check a permission before returning a reference to an
 289      * existing file system. In the case of the {@link FileSystems#getDefault
 290      * default} file system, no permission check is required.
 291      *
 292      * @param   uri
 293      *          URI reference
 294      *
 295      * @return  The file system
 296      *
 297      * @throws  IllegalArgumentException
 298      *          If the pre-conditions for the {@code uri} parameter aren't met
 299      * @throws  FileSystemNotFoundException
 300      *          If the file system does not exist
 301      * @throws  SecurityException
 302      *          If a security manager is installed and it denies an unspecified
 303      *          permission.
 304      */
 305     public abstract FileSystem getFileSystem(URI uri);
 306 
 307     /**
 308      * Return a {@code Path} object by converting the given {@link URI}. The
 309      * resulting {@code Path} is associated with a {@link FileSystem} that
 310      * already exists or is constructed automatically.
 311      *
 312      * <p> The exact form of the URI is file system provider dependent. In the
 313      * case of the default provider, the URI scheme is {@code "file"} and the
 314      * given URI has a non-empty path component, and undefined query, and
 315      * fragment components. The resulting {@code Path} is associated with the
 316      * default {@link FileSystems#getDefault default} {@code FileSystem}.
 317      *
 318      * <p> If a security manager is installed then a provider implementation
 319      * may require to check a permission. In the case of the {@link
 320      * FileSystems#getDefault default} file system, no permission check is
 321      * required.
 322      *
 323      * @param   uri
 324      *          The URI to convert
 325      *
 326      * @return  The resulting {@code Path}
 327      *
 328      * @throws  IllegalArgumentException
 329      *          If the URI scheme does not identify this provider or other
 330      *          preconditions on the uri parameter do not hold
 331      * @throws  FileSystemNotFoundException
 332      *          The file system, identified by the URI, does not exist and
 333      *          cannot be created automatically
 334      * @throws  SecurityException
 335      *          If a security manager is installed and it denies an unspecified
 336      *          permission.
 337      */
 338     public abstract Path getPath(URI uri);
 339 
 340     /**
 341      * Constructs a new {@code FileSystem} to access the contents of a file as a
 342      * file system.
 343      *
 344      * <p> This method is intended for specialized providers of pseudo file
 345      * systems where the contents of one or more files is treated as a file
 346      * system. The {@code env} parameter is a map of provider specific properties
 347      * to configure the file system.
 348      *
 349      * <p> If this provider does not support the creation of such file systems
 350      * or if the provider does not recognize the file type of the given file then
 351      * it throws {@code UnsupportedOperationException}. The default implementation
 352      * of this method throws {@code UnsupportedOperationException}.
 353      *
 354      * @param   path
 355      *          The path to the file
 356      * @param   env
 357      *          A map of provider specific properties to configure the file system;
 358      *          may be empty
 359      *
 360      * @return  A new file system
 361      *
 362      * @throws  UnsupportedOperationException
 363      *          If this provider does not support access to the contents as a
 364      *          file system or it does not recognize the file type of the
 365      *          given file
 366      * @throws  IllegalArgumentException
 367      *          If the {@code env} parameter does not contain properties required
 368      *          by the provider, or a property value is invalid
 369      * @throws  IOException
 370      *          If an I/O error occurs
 371      * @throws  SecurityException
 372      *          If a security manager is installed and it denies an unspecified
 373      *          permission.
 374      */
 375     public FileSystem newFileSystem(Path path, Map<String,?> env)
 376         throws IOException
 377     {
 378         throw new UnsupportedOperationException();
 379     }
 380 
 381     /**
 382      * Opens a file, returning an input stream to read from the file. This
 383      * method works in exactly the manner specified by the {@link
 384      * Files#newInputStream} method.
 385      *
 386      * <p> The default implementation of this method opens a channel to the file
 387      * as if by invoking the {@link #newByteChannel} method and constructs a
 388      * stream that reads bytes from the channel. This method should be overridden
 389      * where appropriate.
 390      *
 391      * @param   path
 392      *          the path to the file to open
 393      * @param   options
 394      *          options specifying how the file is opened
 395      *
 396      * @return  a new input stream
 397      *
 398      * @throws  IllegalArgumentException
 399      *          if an invalid combination of options is specified
 400      * @throws  UnsupportedOperationException
 401      *          if an unsupported option is specified
 402      * @throws  IOException
 403      *          if an I/O error occurs
 404      * @throws  SecurityException
 405      *          In the case of the default provider, and a security manager is
 406      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 407      *          method is invoked to check read access to the file.
 408      */
 409     public InputStream newInputStream(Path path, OpenOption... options)
 410         throws IOException
 411     {
 412         if (options.length > 0) {
 413             for (OpenOption opt: options) {
 414                 // All OpenOption values except for APPEND and WRITE are allowed
 415                 if (opt == StandardOpenOption.APPEND ||
 416                     opt == StandardOpenOption.WRITE)
 417                     throw new UnsupportedOperationException("'" + opt + "' not allowed");
 418             }
 419         }
 420         ReadableByteChannel rbc = Files.newByteChannel(path, options);
 421         if (rbc instanceof FileChannelImpl) {
 422             ((FileChannelImpl) rbc).setUninterruptible();
 423         }
 424         return Channels.newInputStream(rbc);
 425     }
 426 
 427     private static final Set<OpenOption> DEFAULT_OPEN_OPTIONS =
 428         Set.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING,
 429             StandardOpenOption.WRITE);
 430 
 431     /**
 432      * Opens or creates a file, returning an output stream that may be used to
 433      * write bytes to the file. This method works in exactly the manner
 434      * specified by the {@link Files#newOutputStream} method.
 435      *
 436      * <p> The default implementation of this method opens a channel to the file
 437      * as if by invoking the {@link #newByteChannel} method and constructs a
 438      * stream that writes bytes to the channel. This method should be overridden
 439      * where appropriate.
 440      *
 441      * @param   path
 442      *          the path to the file to open or create
 443      * @param   options
 444      *          options specifying how the file is opened
 445      *
 446      * @return  a new output stream
 447      *
 448      * @throws  IllegalArgumentException
 449      *          if {@code options} contains an invalid combination of options
 450      * @throws  UnsupportedOperationException
 451      *          if an unsupported option is specified
 452      * @throws  IOException
 453      *          if an I/O error occurs
 454      * @throws  SecurityException
 455      *          In the case of the default provider, and a security manager is
 456      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 457      *          method is invoked to check write access to the file. The {@link
 458      *          SecurityManager#checkDelete(String) checkDelete} method is
 459      *          invoked to check delete access if the file is opened with the
 460      *          {@code DELETE_ON_CLOSE} option.
 461      */
 462     public OutputStream newOutputStream(Path path, OpenOption... options)
 463         throws IOException
 464     {
 465         int len = options.length;
 466         Set<OpenOption> opts ;
 467         if (len == 0) {
 468             opts = DEFAULT_OPEN_OPTIONS;
 469         } else {
 470             opts = new HashSet<>();
 471             for (OpenOption opt: options) {
 472                 if (opt == StandardOpenOption.READ)
 473                     throw new IllegalArgumentException("READ not allowed");
 474                 opts.add(opt);
 475             }
 476             opts.add(StandardOpenOption.WRITE);
 477         }
 478         WritableByteChannel wbc = newByteChannel(path, opts);
 479         if (wbc instanceof FileChannelImpl) {
 480             ((FileChannelImpl) wbc).setUninterruptible();
 481         }
 482         return Channels.newOutputStream(wbc);
 483     }
 484 
 485     /**
 486      * Opens or creates a file for reading and/or writing, returning a file
 487      * channel to access the file. This method works in exactly the manner
 488      * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
 489      * FileChannel.open} method. A provider that does not support all the
 490      * features required to construct a file channel throws {@code
 491      * UnsupportedOperationException}. The default provider is required to
 492      * support the creation of file channels. When not overridden, the default
 493      * implementation throws {@code UnsupportedOperationException}.
 494      *
 495      * @param   path
 496      *          the path of the file to open or create
 497      * @param   options
 498      *          options specifying how the file is opened
 499      * @param   attrs
 500      *          an optional list of file attributes to set atomically when
 501      *          creating the file
 502      *
 503      * @return  a new file channel
 504      *
 505      * @throws  IllegalArgumentException
 506      *          If the set contains an invalid combination of options
 507      * @throws  UnsupportedOperationException
 508      *          If this provider that does not support creating file channels,
 509      *          or an unsupported open option or file attribute is specified
 510      * @throws  IOException
 511      *          If an I/O error occurs
 512      * @throws  SecurityException
 513      *          In the case of the default file system, the {@link
 514      *          SecurityManager#checkRead(String)} method is invoked to check
 515      *          read access if the file is opened for reading. The {@link
 516      *          SecurityManager#checkWrite(String)} method is invoked to check
 517      *          write access if the file is opened for writing
 518      */
 519     public FileChannel newFileChannel(Path path,
 520                                       Set<? extends OpenOption> options,
 521                                       FileAttribute<?>... attrs)
 522         throws IOException
 523     {
 524         throw new UnsupportedOperationException();
 525     }
 526 
 527     /**
 528      * Opens or creates a file for reading and/or writing, returning an
 529      * asynchronous file channel to access the file. This method works in
 530      * exactly the manner specified by the {@link
 531      * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
 532      * AsynchronousFileChannel.open} method.
 533      * A provider that does not support all the features required to construct
 534      * an asynchronous file channel throws {@code UnsupportedOperationException}.
 535      * The default provider is required to support the creation of asynchronous
 536      * file channels. When not overridden, the default implementation of this
 537      * method throws {@code UnsupportedOperationException}.
 538      *
 539      * @param   path
 540      *          the path of the file to open or create
 541      * @param   options
 542      *          options specifying how the file is opened
 543      * @param   executor
 544      *          the thread pool or {@code null} to associate the channel with
 545      *          the default thread pool
 546      * @param   attrs
 547      *          an optional list of file attributes to set atomically when
 548      *          creating the file
 549      *
 550      * @return  a new asynchronous file channel
 551      *
 552      * @throws  IllegalArgumentException
 553      *          If the set contains an invalid combination of options
 554      * @throws  UnsupportedOperationException
 555      *          If this provider that does not support creating asynchronous file
 556      *          channels, or an unsupported open option or file attribute is
 557      *          specified
 558      * @throws  IOException
 559      *          If an I/O error occurs
 560      * @throws  SecurityException
 561      *          In the case of the default file system, the {@link
 562      *          SecurityManager#checkRead(String)} method is invoked to check
 563      *          read access if the file is opened for reading. The {@link
 564      *          SecurityManager#checkWrite(String)} method is invoked to check
 565      *          write access if the file is opened for writing
 566      */
 567     public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
 568                                                               Set<? extends OpenOption> options,
 569                                                               ExecutorService executor,
 570                                                               FileAttribute<?>... attrs)
 571         throws IOException
 572     {
 573         throw new UnsupportedOperationException();
 574     }
 575 
 576     /**
 577      * Opens or creates a file, returning a seekable byte channel to access the
 578      * file. This method works in exactly the manner specified by the {@link
 579      * Files#newByteChannel(Path,Set,FileAttribute[])} method.
 580      *
 581      * @param   path
 582      *          the path to the file to open or create
 583      * @param   options
 584      *          options specifying how the file is opened
 585      * @param   attrs
 586      *          an optional list of file attributes to set atomically when
 587      *          creating the file
 588      *
 589      * @return  a new seekable byte channel
 590      *
 591      * @throws  IllegalArgumentException
 592      *          if the set contains an invalid combination of options
 593      * @throws  UnsupportedOperationException
 594      *          if an unsupported open option is specified or the array contains
 595      *          attributes that cannot be set atomically when creating the file
 596      * @throws  FileAlreadyExistsException
 597      *          if a file of that name already exists and the {@link
 598      *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
 599      *          <i>(optional specific exception)</i>
 600      * @throws  IOException
 601      *          if an I/O error occurs
 602      * @throws  SecurityException
 603      *          In the case of the default provider, and a security manager is
 604      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 605      *          method is invoked to check read access to the path if the file is
 606      *          opened for reading. The {@link SecurityManager#checkWrite(String)
 607      *          checkWrite} method is invoked to check write access to the path
 608      *          if the file is opened for writing. The {@link
 609      *          SecurityManager#checkDelete(String) checkDelete} method is
 610      *          invoked to check delete access if the file is opened with the
 611      *          {@code DELETE_ON_CLOSE} option.
 612      */
 613     public abstract SeekableByteChannel newByteChannel(Path path,
 614         Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
 615 
 616     /**
 617      * Opens a directory, returning a {@code DirectoryStream} to iterate over
 618      * the entries in the directory. This method works in exactly the manner
 619      * specified by the {@link
 620      * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
 621      * method.
 622      *
 623      * @param   dir
 624      *          the path to the directory
 625      * @param   filter
 626      *          the directory stream filter
 627      *
 628      * @return  a new and open {@code DirectoryStream} object
 629      *
 630      * @throws  NotDirectoryException
 631      *          if the file could not otherwise be opened because it is not
 632      *          a directory <i>(optional specific exception)</i>
 633      * @throws  IOException
 634      *          if an I/O error occurs
 635      * @throws  SecurityException
 636      *          In the case of the default provider, and a security manager is
 637      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 638      *          method is invoked to check read access to the directory.
 639      */
 640     public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
 641          DirectoryStream.Filter<? super Path> filter) throws IOException;
 642 
 643     /**
 644      * Creates a new directory. This method works in exactly the manner
 645      * specified by the {@link Files#createDirectory} method.
 646      *
 647      * @param   dir
 648      *          the directory to create
 649      * @param   attrs
 650      *          an optional list of file attributes to set atomically when
 651      *          creating the directory
 652      *
 653      * @throws  UnsupportedOperationException
 654      *          if the array contains an attribute that cannot be set atomically
 655      *          when creating the directory
 656      * @throws  FileAlreadyExistsException
 657      *          if a directory could not otherwise be created because a file of
 658      *          that name already exists <i>(optional specific exception)</i>
 659      * @throws  IOException
 660      *          if an I/O error occurs or the parent directory does not exist
 661      * @throws  SecurityException
 662      *          In the case of the default provider, and a security manager is
 663      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 664      *          method is invoked to check write access to the new directory.
 665      */
 666     public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
 667         throws IOException;
 668 
 669     /**
 670      * Creates a symbolic link to a target. This method works in exactly the
 671      * manner specified by the {@link Files#createSymbolicLink} method.
 672      *
 673      * <p> The default implementation of this method throws {@code
 674      * UnsupportedOperationException}.
 675      *
 676      * @param   link
 677      *          the path of the symbolic link to create
 678      * @param   target
 679      *          the target of the symbolic link
 680      * @param   attrs
 681      *          the array of attributes to set atomically when creating the
 682      *          symbolic link
 683      *
 684      * @throws  UnsupportedOperationException
 685      *          if the implementation does not support symbolic links or the
 686      *          array contains an attribute that cannot be set atomically when
 687      *          creating the symbolic link
 688      * @throws  FileAlreadyExistsException
 689      *          if a file with the name already exists <i>(optional specific
 690      *          exception)</i>
 691      * @throws  IOException
 692      *          if an I/O error occurs
 693      * @throws  SecurityException
 694      *          In the case of the default provider, and a security manager
 695      *          is installed, it denies {@link LinkPermission}{@code ("symbolic")}
 696      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
 697      *          method denies write access to the path of the symbolic link.
 698      */
 699     public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
 700         throws IOException
 701     {
 702         throw new UnsupportedOperationException();
 703     }
 704 
 705     /**
 706      * Creates a new link (directory entry) for an existing file. This method
 707      * works in exactly the manner specified by the {@link Files#createLink}
 708      * method.
 709      *
 710      * <p> The default implementation of this method throws {@code
 711      * UnsupportedOperationException}.
 712      *
 713      * @param   link
 714      *          the link (directory entry) to create
 715      * @param   existing
 716      *          a path to an existing file
 717      *
 718      * @throws  UnsupportedOperationException
 719      *          if the implementation does not support adding an existing file
 720      *          to a directory
 721      * @throws  FileAlreadyExistsException
 722      *          if the entry could not otherwise be created because a file of
 723      *          that name already exists <i>(optional specific exception)</i>
 724      * @throws  IOException
 725      *          if an I/O error occurs
 726      * @throws  SecurityException
 727      *          In the case of the default provider, and a security manager
 728      *          is installed, it denies {@link LinkPermission}{@code ("hard")}
 729      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
 730      *          method denies write access to either the  link or the
 731      *          existing file.
 732      */
 733     public void createLink(Path link, Path existing) throws IOException {
 734         throw new UnsupportedOperationException();
 735     }
 736 
 737     /**
 738      * Deletes a file. This method works in exactly the  manner specified by the
 739      * {@link Files#delete} method.
 740      *
 741      * @param   path
 742      *          the path to the file to delete
 743      *
 744      * @throws  NoSuchFileException
 745      *          if the file does not exist <i>(optional specific exception)</i>
 746      * @throws  DirectoryNotEmptyException
 747      *          if the file is a directory and could not otherwise be deleted
 748      *          because the directory is not empty <i>(optional specific
 749      *          exception)</i>
 750      * @throws  IOException
 751      *          if an I/O error occurs
 752      * @throws  SecurityException
 753      *          In the case of the default provider, and a security manager is
 754      *          installed, the {@link SecurityManager#checkDelete(String)} method
 755      *          is invoked to check delete access to the file
 756      */
 757     public abstract void delete(Path path) throws IOException;
 758 
 759     /**
 760      * Deletes a file if it exists. This method works in exactly the manner
 761      * specified by the {@link Files#deleteIfExists} method.
 762      *
 763      * <p> The default implementation of this method simply invokes {@link
 764      * #delete} ignoring the {@code NoSuchFileException} when the file does not
 765      * exist. It may be overridden where appropriate.
 766      *
 767      * @param   path
 768      *          the path to the file to delete
 769      *
 770      * @return  {@code true} if the file was deleted by this method; {@code
 771      *          false} if the file could not be deleted because it did not
 772      *          exist
 773      *
 774      * @throws  DirectoryNotEmptyException
 775      *          if the file is a directory and could not otherwise be deleted
 776      *          because the directory is not empty <i>(optional specific
 777      *          exception)</i>
 778      * @throws  IOException
 779      *          if an I/O error occurs
 780      * @throws  SecurityException
 781      *          In the case of the default provider, and a security manager is
 782      *          installed, the {@link SecurityManager#checkDelete(String)} method
 783      *          is invoked to check delete access to the file
 784      */
 785     public boolean deleteIfExists(Path path) throws IOException {
 786         try {
 787             delete(path);
 788             return true;
 789         } catch (NoSuchFileException ignore) {
 790             return false;
 791         }
 792     }
 793 
 794     /**
 795      * Reads the target of a symbolic link. This method works in exactly the
 796      * manner specified by the {@link Files#readSymbolicLink} method.
 797      *
 798      * <p> The default implementation of this method throws {@code
 799      * UnsupportedOperationException}.
 800      *
 801      * @param   link
 802      *          the path to the symbolic link
 803      *
 804      * @return  The target of the symbolic link
 805      *
 806      * @throws  UnsupportedOperationException
 807      *          if the implementation does not support symbolic links
 808      * @throws  NotLinkException
 809      *          if the target could otherwise not be read because the file
 810      *          is not a symbolic link <i>(optional specific exception)</i>
 811      * @throws  IOException
 812      *          if an I/O error occurs
 813      * @throws  SecurityException
 814      *          In the case of the default provider, and a security manager
 815      *          is installed, it checks that {@code FilePermission} has been
 816      *          granted with the "{@code readlink}" action to read the link.
 817      */
 818     public Path readSymbolicLink(Path link) throws IOException {
 819         throw new UnsupportedOperationException();
 820     }
 821 
 822     /**
 823      * Copy a file to a target file. This method works in exactly the manner
 824      * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
 825      * except that both the source and target paths must be associated with
 826      * this provider.
 827      *
 828      * @param   source
 829      *          the path to the file to copy
 830      * @param   target
 831      *          the path to the target file
 832      * @param   options
 833      *          options specifying how the copy should be done
 834      *
 835      * @throws  UnsupportedOperationException
 836      *          if the array contains a copy option that is not supported
 837      * @throws  FileAlreadyExistsException
 838      *          if the target file exists but cannot be replaced because the
 839      *          {@code REPLACE_EXISTING} option is not specified <i>(optional
 840      *          specific exception)</i>
 841      * @throws  DirectoryNotEmptyException
 842      *          the {@code REPLACE_EXISTING} option is specified but the file
 843      *          cannot be replaced because it is a non-empty directory
 844      *          <i>(optional specific exception)</i>
 845      * @throws  IOException
 846      *          if an I/O error occurs
 847      * @throws  SecurityException
 848      *          In the case of the default provider, and a security manager is
 849      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 850      *          method is invoked to check read access to the source file, the
 851      *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
 852      *          to check write access to the target file. If a symbolic link is
 853      *          copied the security manager is invoked to check {@link
 854      *          LinkPermission}{@code ("symbolic")}.
 855      */
 856     public abstract void copy(Path source, Path target, CopyOption... options)
 857         throws IOException;
 858 
 859     /**
 860      * Move or rename a file to a target file. This method works in exactly the
 861      * manner specified by the {@link Files#move} method except that both the
 862      * source and target paths must be associated with this provider.
 863      *
 864      * @param   source
 865      *          the path to the file to move
 866      * @param   target
 867      *          the path to the target file
 868      * @param   options
 869      *          options specifying how the move should be done
 870      *
 871      * @throws  UnsupportedOperationException
 872      *          if the array contains a copy option that is not supported
 873      * @throws  FileAlreadyExistsException
 874      *          if the target file exists but cannot be replaced because the
 875      *          {@code REPLACE_EXISTING} option is not specified <i>(optional
 876      *          specific exception)</i>
 877      * @throws  DirectoryNotEmptyException
 878      *          the {@code REPLACE_EXISTING} option is specified but the file
 879      *          cannot be replaced because it is a non-empty directory
 880      *          <i>(optional specific exception)</i>
 881      * @throws  AtomicMoveNotSupportedException
 882      *          if the options array contains the {@code ATOMIC_MOVE} option but
 883      *          the file cannot be moved as an atomic file system operation.
 884      * @throws  IOException
 885      *          if an I/O error occurs
 886      * @throws  SecurityException
 887      *          In the case of the default provider, and a security manager is
 888      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 889      *          method is invoked to check write access to both the source and
 890      *          target file.
 891      */
 892     public abstract void move(Path source, Path target, CopyOption... options)
 893         throws IOException;
 894 
 895     /**
 896      * Tests if two paths locate the same file. This method works in exactly the
 897      * manner specified by the {@link Files#isSameFile} method.
 898      *
 899      * @param   path
 900      *          one path to the file
 901      * @param   path2
 902      *          the other path
 903      *
 904      * @return  {@code true} if, and only if, the two paths locate the same file
 905      *
 906      * @throws  IOException
 907      *          if an I/O error occurs
 908      * @throws  SecurityException
 909      *          In the case of the default provider, and a security manager is
 910      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 911      *          method is invoked to check read access to both files.
 912      */
 913     public abstract boolean isSameFile(Path path, Path path2)
 914         throws IOException;
 915 
 916     /**
 917      * Tells whether or not a file is considered <em>hidden</em>. This method
 918      * works in exactly the manner specified by the {@link Files#isHidden}
 919      * method.
 920      *
 921      * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
 922      *
 923      * @param   path
 924      *          the path to the file to test
 925      *
 926      * @return  {@code true} if the file is considered hidden
 927      *
 928      * @throws  IOException
 929      *          if an I/O error occurs
 930      * @throws  SecurityException
 931      *          In the case of the default provider, and a security manager is
 932      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 933      *          method is invoked to check read access to the file.
 934      */
 935     public abstract boolean isHidden(Path path) throws IOException;
 936 
 937     /**
 938      * Returns the {@link FileStore} representing the file store where a file
 939      * is located. This method works in exactly the manner specified by the
 940      * {@link Files#getFileStore} method.
 941      *
 942      * @param   path
 943      *          the path to the file
 944      *
 945      * @return  the file store where the file is stored
 946      *
 947      * @throws  IOException
 948      *          if an I/O error occurs
 949      * @throws  SecurityException
 950      *          In the case of the default provider, and a security manager is
 951      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 952      *          method is invoked to check read access to the file, and in
 953      *          addition it checks
 954      *          {@link RuntimePermission}{@code ("getFileStoreAttributes")}
 955      */
 956     public abstract FileStore getFileStore(Path path) throws IOException;
 957 
 958     /**
 959      * Checks the existence, and optionally the accessibility, of a file.
 960      *
 961      * <p> This method may be used by the {@link Files#isReadable isReadable},
 962      * {@link Files#isWritable isWritable} and {@link Files#isExecutable
 963      * isExecutable} methods to check the accessibility of a file.
 964      *
 965      * <p> This method checks the existence of a file and that this Java virtual
 966      * machine has appropriate privileges that would allow it access the file
 967      * according to all of access modes specified in the {@code modes} parameter
 968      * as follows:
 969      *
 970      * <table class="striped">
 971      * <caption style="display:none">Access Modes</caption>
 972      * <thead>
 973      * <tr> <th scope="col">Value</th> <th scope="col">Description</th> </tr>
 974      * </thead>
 975      * <tbody>
 976      * <tr>
 977      *   <th scope="row"> {@link AccessMode#READ READ} </th>
 978      *   <td> Checks that the file exists and that the Java virtual machine has
 979      *     permission to read the file. </td>
 980      * </tr>
 981      * <tr>
 982      *   <th scope="row"> {@link AccessMode#WRITE WRITE} </th>
 983      *   <td> Checks that the file exists and that the Java virtual machine has
 984      *     permission to write to the file, </td>
 985      * </tr>
 986      * <tr>
 987      *   <th scope="row"> {@link AccessMode#EXECUTE EXECUTE} </th>
 988      *   <td> Checks that the file exists and that the Java virtual machine has
 989      *     permission to {@link Runtime#exec execute} the file. The semantics
 990      *     may differ when checking access to a directory. For example, on UNIX
 991      *     systems, checking for {@code EXECUTE} access checks that the Java
 992      *     virtual machine has permission to search the directory in order to
 993      *     access file or subdirectories. </td>
 994      * </tr>
 995      * </tbody>
 996      * </table>
 997      *
 998      * <p> If the {@code modes} parameter is of length zero, then the existence
 999      * of the file is checked.
1000      *
1001      * <p> This method follows symbolic links if the file referenced by this
1002      * object is a symbolic link. Depending on the implementation, this method
1003      * may require to read file permissions, access control lists, or other
1004      * file attributes in order to check the effective access to the file. To
1005      * determine the effective access to a file may require access to several
1006      * attributes and so in some implementations this method may not be atomic
1007      * with respect to other file system operations.
1008      *
1009      * @param   path
1010      *          the path to the file to check
1011      * @param   modes
1012      *          The access modes to check; may have zero elements
1013      *
1014      * @throws  UnsupportedOperationException
1015      *          an implementation is required to support checking for
1016      *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
1017      *          exception is specified to allow for the {@code Access} enum to
1018      *          be extended in future releases.
1019      * @throws  NoSuchFileException
1020      *          if a file does not exist <i>(optional specific exception)</i>
1021      * @throws  AccessDeniedException
1022      *          the requested access would be denied or the access cannot be
1023      *          determined because the Java virtual machine has insufficient
1024      *          privileges or other reasons. <i>(optional specific exception)</i>
1025      * @throws  IOException
1026      *          if an I/O error occurs
1027      * @throws  SecurityException
1028      *          In the case of the default provider, and a security manager is
1029      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
1030      *          is invoked when checking read access to the file or only the
1031      *          existence of the file, the {@link SecurityManager#checkWrite(String)
1032      *          checkWrite} is invoked when checking write access to the file,
1033      *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
1034      *          when checking execute access.
1035      */
1036     public abstract void checkAccess(Path path, AccessMode... modes)
1037         throws IOException;
1038 
1039     /**
1040      * Returns a file attribute view of a given type. This method works in
1041      * exactly the manner specified by the {@link Files#getFileAttributeView}
1042      * method.
1043      *
1044      * @param   <V>
1045      *          The {@code FileAttributeView} type
1046      * @param   path
1047      *          the path to the file
1048      * @param   type
1049      *          the {@code Class} object corresponding to the file attribute view
1050      * @param   options
1051      *          options indicating how symbolic links are handled
1052      *
1053      * @return  a file attribute view of the specified type, or {@code null} if
1054      *          the attribute view type is not available
1055      */
1056     public abstract <V extends FileAttributeView> V
1057         getFileAttributeView(Path path, Class<V> type, LinkOption... options);
1058 
1059     /**
1060      * Reads a file's attributes as a bulk operation. This method works in
1061      * exactly the manner specified by the {@link
1062      * Files#readAttributes(Path,Class,LinkOption[])} method.
1063      *
1064      * @param   <A>
1065      *          The {@code BasicFileAttributes} type
1066      * @param   path
1067      *          the path to the file
1068      * @param   type
1069      *          the {@code Class} of the file attributes required
1070      *          to read
1071      * @param   options
1072      *          options indicating how symbolic links are handled
1073      *
1074      * @return  the file attributes
1075      *
1076      * @throws  UnsupportedOperationException
1077      *          if an attributes of the given type are not supported
1078      * @throws  IOException
1079      *          if an I/O error occurs
1080      * @throws  SecurityException
1081      *          In the case of the default provider, a security manager is
1082      *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1083      *          method is invoked to check read access to the file
1084      */
1085     public abstract <A extends BasicFileAttributes> A
1086         readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
1087 
1088     /**
1089      * Reads a set of file attributes as a bulk operation. This method works in
1090      * exactly the manner specified by the {@link
1091      * Files#readAttributes(Path,String,LinkOption[])} method.
1092      *
1093      * @param   path
1094      *          the path to the file
1095      * @param   attributes
1096      *          the attributes to read
1097      * @param   options
1098      *          options indicating how symbolic links are handled
1099      *
1100      * @return  a map of the attributes returned; may be empty. The map's keys
1101      *          are the attribute names, its values are the attribute values
1102      *
1103      * @throws  UnsupportedOperationException
1104      *          if the attribute view is not available
1105      * @throws  IllegalArgumentException
1106      *          if no attributes are specified or an unrecognized attributes is
1107      *          specified
1108      * @throws  IOException
1109      *          If an I/O error occurs
1110      * @throws  SecurityException
1111      *          In the case of the default provider, and a security manager is
1112      *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1113      *          method denies read access to the file. If this method is invoked
1114      *          to read security sensitive attributes then the security manager
1115      *          may be invoke to check for additional permissions.
1116      */
1117     public abstract Map<String,Object> readAttributes(Path path, String attributes,
1118                                                       LinkOption... options)
1119         throws IOException;
1120 
1121     /**
1122      * Sets the value of a file attribute. This method works in exactly the
1123      * manner specified by the {@link Files#setAttribute} method.
1124      *
1125      * @param   path
1126      *          the path to the file
1127      * @param   attribute
1128      *          the attribute to set
1129      * @param   value
1130      *          the attribute value
1131      * @param   options
1132      *          options indicating how symbolic links are handled
1133      *
1134      * @throws  UnsupportedOperationException
1135      *          if the attribute view is not available
1136      * @throws  IllegalArgumentException
1137      *          if the attribute name is not specified, or is not recognized, or
1138      *          the attribute value is of the correct type but has an
1139      *          inappropriate value
1140      * @throws  ClassCastException
1141      *          If the attribute value is not of the expected type or is a
1142      *          collection containing elements that are not of the expected
1143      *          type
1144      * @throws  IOException
1145      *          If an I/O error occurs
1146      * @throws  SecurityException
1147      *          In the case of the default provider, and a security manager is
1148      *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
1149      *          method denies write access to the file. If this method is invoked
1150      *          to set security sensitive attributes then the security manager
1151      *          may be invoked to check for additional permissions.
1152      */
1153     public abstract void setAttribute(Path path, String attribute,
1154                                       Object value, LinkOption... options)
1155         throws IOException;
1156 }