Path: blob/master/src/java.base/share/classes/java/nio/file/FileSystems.java
41159 views
/*1* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.nio.file;2627import java.nio.file.spi.FileSystemProvider;28import java.net.URI;29import java.io.IOException;30import java.security.AccessController;31import java.security.PrivilegedAction;32import java.lang.reflect.Constructor;33import java.util.Collections;34import java.util.Map;35import java.util.ServiceConfigurationError;36import java.util.ServiceLoader;3738import jdk.internal.misc.VM;39import sun.nio.fs.DefaultFileSystemProvider;4041/**42* Factory methods for file systems. This class defines the {@link #getDefault43* getDefault} method to get the default file system and factory methods to44* construct other types of file systems.45*46* <p> The first invocation of any of the methods defined by this class causes47* the default {@link FileSystemProvider provider} to be loaded. The default48* provider, identified by the URI scheme "file", creates the {@link FileSystem}49* that provides access to the file systems accessible to the Java virtual50* machine. If the process of loading or initializing the default provider fails51* then an unspecified error is thrown.52*53* <p> The first invocation of the {@link FileSystemProvider#installedProviders()54* installedProviders} method, by way of invoking any of the {@code55* newFileSystem} methods defined by this class, locates and loads all56* installed file system providers. Installed providers are loaded using the57* service-provider loading facility defined by the {@link ServiceLoader} class.58* Installed providers are loaded using the system class loader. If the59* system class loader cannot be found then the platform class loader is used.60* Providers are typically installed by placing them in a JAR file on the61* application class path, the JAR file contains a62* provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}63* in the resource directory {@code META-INF/services}, and the file lists one or64* more fully-qualified names of concrete subclass of {@link FileSystemProvider}65* that have a zero argument constructor.66* The ordering that installed providers are located is implementation specific.67* If a provider is instantiated and its {@link FileSystemProvider#getScheme()68* getScheme} returns the same URI scheme of a provider that was previously69* instantiated then the most recently instantiated duplicate is discarded. URI70* schemes are compared without regard to case. During construction a provider71* may safely access files associated with the default provider but care needs72* to be taken to avoid circular loading of other installed providers. If73* circular loading of installed providers is detected then an unspecified error74* is thrown.75*76* <p> This class also defines factory methods that allow a {@link ClassLoader}77* to be specified when locating a provider. As with installed providers, the78* provider classes are identified by placing the provider configuration file79* in the resource directory {@code META-INF/services}.80*81* <p> If a thread initiates the loading of the installed file system providers82* and another thread invokes a method that also attempts to load the providers83* then the method will block until the loading completes.84*85* @since 1.786*/8788public final class FileSystems {89private FileSystems() { }9091// lazy initialization of default file system92private static class DefaultFileSystemHolder {93static final FileSystem defaultFileSystem = defaultFileSystem();9495// returns default file system96private static FileSystem defaultFileSystem() {97// load default provider98@SuppressWarnings("removal")99FileSystemProvider provider = AccessController100.doPrivileged(new PrivilegedAction<>() {101public FileSystemProvider run() {102return getDefaultProvider();103}104});105106// return file system107return provider.getFileSystem(URI.create("file:///"));108}109110// returns default provider111private static FileSystemProvider getDefaultProvider() {112// start with the platform's default file system provider113FileSystemProvider provider = DefaultFileSystemProvider.instance();114115// if the property java.nio.file.spi.DefaultFileSystemProvider is116// set then its value is the name of the default provider (or a list)117String prop = "java.nio.file.spi.DefaultFileSystemProvider";118String propValue = System.getProperty(prop);119if (propValue != null) {120for (String cn: propValue.split(",")) {121try {122Class<?> c = Class123.forName(cn, true, ClassLoader.getSystemClassLoader());124Constructor<?> ctor = c125.getDeclaredConstructor(FileSystemProvider.class);126provider = (FileSystemProvider)ctor.newInstance(provider);127128// must be "file"129if (!provider.getScheme().equals("file"))130throw new Error("Default provider must use scheme 'file'");131132} catch (Exception x) {133throw new Error(x);134}135}136}137return provider;138}139}140141/**142* Returns the default {@code FileSystem}. The default file system creates143* objects that provide access to the file systems accessible to the Java144* virtual machine. The <em>working directory</em> of the file system is145* the current user directory, named by the system property {@code user.dir}.146* This allows for interoperability with the {@link java.io.File java.io.File}147* class.148*149* <p> The first invocation of any of the methods defined by this class150* locates the default {@link FileSystemProvider provider} object. Where the151* system property {@code java.nio.file.spi.DefaultFileSystemProvider} is152* not defined then the default provider is a system-default provider that153* is invoked to create the default file system.154*155* <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}156* is defined then it is taken to be a list of one or more fully-qualified157* names of concrete provider classes identified by the URI scheme158* {@code "file"}. Where the property is a list of more than one name then159* the names are separated by a comma. Each class is loaded, using the system160* class loader, and instantiated by invoking a one argument constructor161* whose formal parameter type is {@code FileSystemProvider}. The providers162* are loaded and instantiated in the order they are listed in the property.163* If this process fails or a provider's scheme is not equal to {@code "file"}164* then an unspecified error is thrown. URI schemes are normally compared165* without regard to case but for the default provider, the scheme is166* required to be {@code "file"}. The first provider class is instantiated167* by invoking it with a reference to the system-default provider.168* The second provider class is instantiated by invoking it with a reference169* to the first provider instance. The third provider class is instantiated170* by invoking it with a reference to the second instance, and so on. The171* last provider to be instantiated becomes the default provider; its {@code172* getFileSystem} method is invoked with the URI {@code "file:///"} to173* get a reference to the default file system.174*175* <p> Subsequent invocations of this method return the file system that was176* returned by the first invocation.177*178* @return the default file system179*/180public static FileSystem getDefault() {181if (VM.isModuleSystemInited()) {182return DefaultFileSystemHolder.defaultFileSystem;183} else {184// always use the platform's default file system during startup185return DefaultFileSystemProvider.theFileSystem();186}187}188189/**190* Returns a reference to an existing {@code FileSystem}.191*192* <p> This method iterates over the {@link FileSystemProvider#installedProviders()193* installed} providers to locate the provider that is identified by the URI194* {@link URI#getScheme scheme} of the given URI. URI schemes are compared195* without regard to case. The exact form of the URI is highly provider196* dependent. If found, the provider's {@link FileSystemProvider#getFileSystem197* getFileSystem} method is invoked to obtain a reference to the {@code198* FileSystem}.199*200* <p> Once a file system created by this provider is {@link FileSystem#close201* closed} it is provider-dependent if this method returns a reference to202* the closed file system or throws {@link FileSystemNotFoundException}.203* If the provider allows a new file system to be created with the same URI204* as a file system it previously created then this method throws the205* exception if invoked after the file system is closed (and before a new206* instance is created by the {@link #newFileSystem newFileSystem} method).207*208* <p> If a security manager is installed then a provider implementation209* may require to check a permission before returning a reference to an210* existing file system. In the case of the {@link FileSystems#getDefault211* default} file system, no permission check is required.212*213* @param uri the URI to locate the file system214*215* @return the reference to the file system216*217* @throws IllegalArgumentException218* if the pre-conditions for the {@code uri} parameter are not met219* @throws FileSystemNotFoundException220* if the file system, identified by the URI, does not exist221* @throws ProviderNotFoundException222* if a provider supporting the URI scheme is not installed223* @throws SecurityException224* if a security manager is installed and it denies an unspecified225* permission226*/227public static FileSystem getFileSystem(URI uri) {228String scheme = uri.getScheme();229if (scheme == null) {230throw new IllegalArgumentException(uri.toString());231}232for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {233if (scheme.equalsIgnoreCase(provider.getScheme())) {234return provider.getFileSystem(uri);235}236}237throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");238}239240/**241* Constructs a new file system that is identified by a {@link URI}242*243* <p> This method iterates over the {@link FileSystemProvider#installedProviders()244* installed} providers to locate the provider that is identified by the URI245* {@link URI#getScheme scheme} of the given URI. URI schemes are compared246* without regard to case. The exact form of the URI is highly provider247* dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)248* newFileSystem(URI,Map)} method is invoked to construct the new file system.249*250* <p> Once a file system is {@link FileSystem#close closed} it is251* provider-dependent if the provider allows a new file system to be created252* with the same URI as a file system it previously created.253*254* <p> <b>Usage Example:</b>255* Suppose there is a provider identified by the scheme {@code "memory"}256* installed:257* <pre>258* FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"),259* Map.of("capacity", "16G", "blockSize", "4k"));260* </pre>261*262* @param uri263* the URI identifying the file system264* @param env265* a map of provider specific properties to configure the file system;266* may be empty267*268* @return a new file system269*270* @throws IllegalArgumentException271* if the pre-conditions for the {@code uri} parameter are not met,272* or the {@code env} parameter does not contain properties required273* by the provider, or a property value is invalid274* @throws FileSystemAlreadyExistsException275* if the file system has already been created276* @throws ProviderNotFoundException277* if a provider supporting the URI scheme is not installed278* @throws IOException279* if an I/O error occurs creating the file system280* @throws SecurityException281* if a security manager is installed and it denies an unspecified282* permission required by the file system provider implementation283*/284public static FileSystem newFileSystem(URI uri, Map<String,?> env)285throws IOException286{287return newFileSystem(uri, env, null);288}289290/**291* Constructs a new file system that is identified by a {@link URI}292*293* <p> This method first attempts to locate an installed provider in exactly294* the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}295* method. If none of the installed providers support the URI scheme then an296* attempt is made to locate the provider using the given class loader. If a297* provider supporting the URI scheme is located then its {@link298* FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is299* invoked to construct the new file system.300*301* @param uri302* the URI identifying the file system303* @param env304* a map of provider specific properties to configure the file system;305* may be empty306* @param loader307* the class loader to locate the provider or {@code null} to only308* attempt to locate an installed provider309*310* @return a new file system311*312* @throws IllegalArgumentException313* if the pre-conditions for the {@code uri} parameter are not met,314* or the {@code env} parameter does not contain properties required315* by the provider, or a property value is invalid316* @throws FileSystemAlreadyExistsException317* if the URI scheme identifies an installed provider and the file318* system has already been created319* @throws ProviderNotFoundException320* if a provider supporting the URI scheme is not found321* @throws ServiceConfigurationError322* when an error occurs while loading a service provider323* @throws IOException324* an I/O error occurs creating the file system325* @throws SecurityException326* if a security manager is installed and it denies an unspecified327* permission required by the file system provider implementation328*/329public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)330throws IOException331{332String scheme = uri.getScheme();333334// check installed providers335for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {336if (scheme.equalsIgnoreCase(provider.getScheme())) {337try {338return provider.newFileSystem(uri, env);339} catch (UnsupportedOperationException uoe) {340}341}342}343344// if not found, use service-provider loading facility345if (loader != null) {346ServiceLoader<FileSystemProvider> sl = ServiceLoader347.load(FileSystemProvider.class, loader);348for (FileSystemProvider provider : sl) {349if (scheme.equalsIgnoreCase(provider.getScheme())) {350try {351return provider.newFileSystem(uri, env);352} catch (UnsupportedOperationException uoe) {353}354}355}356}357358throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");359}360361/**362* Constructs a new {@code FileSystem} to access the contents of a file as a363* file system.364*365* <p> This method makes use of specialized providers that create pseudo file366* systems where the contents of one or more files is treated as a file367* system.368*369* <p> This method first attempts to locate an installed provider in exactly370* the same manner as the {@link #newFileSystem(Path, Map, ClassLoader)371* newFileSystem(Path, Map, ClassLoader)} method with an empty map. If none372* of the installed providers return a {@code FileSystem} then an attempt is373* made to locate the provider using the given class loader. If a provider374* returns a file system then the lookup terminates and the file system is375* returned.376*377* @param path378* the path to the file379* @param loader380* the class loader to locate the provider or {@code null} to only381* attempt to locate an installed provider382*383* @return a new file system384*385* @throws ProviderNotFoundException386* if a provider supporting this file type cannot be located387* @throws ServiceConfigurationError388* when an error occurs while loading a service provider389* @throws IOException390* if an I/O error occurs391* @throws SecurityException392* if a security manager is installed and it denies an unspecified393* permission394*/395public static FileSystem newFileSystem(Path path,396ClassLoader loader)397throws IOException398{399return newFileSystem(path, Map.of(), loader);400}401402/**403* Constructs a new {@code FileSystem} to access the contents of a file as a404* file system.405*406* <p> This method makes use of specialized providers that create pseudo file407* systems where the contents of one or more files is treated as a file408* system.409*410* <p> This method first attempts to locate an installed provider in exactly411* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)412* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's413* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}414* method is invoked to construct the new file system.415*416* @param path417* the path to the file418* @param env419* a map of provider specific properties to configure the file system;420* may be empty421*422* @return a new file system423*424* @throws ProviderNotFoundException425* if a provider supporting this file type cannot be located426* @throws ServiceConfigurationError427* when an error occurs while loading a service provider428* @throws IOException429* if an I/O error occurs430* @throws SecurityException431* if a security manager is installed and it denies an unspecified432* permission433*434* @since 13435*/436public static FileSystem newFileSystem(Path path, Map<String,?> env)437throws IOException438{439return newFileSystem(path, env, null);440}441442/**443* Constructs a new {@code FileSystem} to access the contents of a file as a444* file system.445*446* <p> This method makes use of specialized providers that create pseudo file447* systems where the contents of one or more files is treated as a file448* system.449*450* <p> This method first attempts to locate an installed provider in exactly451* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)452* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's453* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}454* method is invoked with an empty map to construct the new file system.455*456* @param path457* the path to the file458*459* @return a new file system460*461* @throws ProviderNotFoundException462* if a provider supporting this file type cannot be located463* @throws ServiceConfigurationError464* when an error occurs while loading a service provider465* @throws IOException466* if an I/O error occurs467* @throws SecurityException468* if a security manager is installed and it denies an unspecified469* permission470*471* @since 13472*/473public static FileSystem newFileSystem(Path path) throws IOException {474return newFileSystem(path, Map.of(), null);475}476477/**478* Constructs a new {@code FileSystem} to access the contents of a file as a479* file system.480*481* <p> This method makes use of specialized providers that create pseudo file482* systems where the contents of one or more files is treated as a file483* system.484*485* <p> This method iterates over the {@link FileSystemProvider#installedProviders()486* installed} providers. It invokes, in turn, each provider's {@link487* FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)}488* method. If a provider returns a file system then the iteration489* terminates and the file system is returned.490* If none of the installed providers return a {@code FileSystem} then491* an attempt is made to locate the provider using the given class loader.492* If a provider returns a file493* system, then the lookup terminates and the file system is returned.494*495* @param path496* the path to the file497* @param env498* a map of provider specific properties to configure the file system;499* may be empty500* @param loader501* the class loader to locate the provider or {@code null} to only502* attempt to locate an installed provider503*504* @return a new file system505*506* @throws ProviderNotFoundException507* if a provider supporting this file type cannot be located508* @throws ServiceConfigurationError509* when an error occurs while loading a service provider510* @throws IOException511* if an I/O error occurs512* @throws SecurityException513* if a security manager is installed and it denies an unspecified514* permission515*516* @since 13517*/518public static FileSystem newFileSystem(Path path, Map<String,?> env,519ClassLoader loader)520throws IOException521{522if (path == null)523throw new NullPointerException();524// check installed providers525for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {526try {527return provider.newFileSystem(path, env);528} catch (UnsupportedOperationException uoe) {529}530}531532// if not found, use service-provider loading facility533if (loader != null) {534ServiceLoader<FileSystemProvider> sl = ServiceLoader535.load(FileSystemProvider.class, loader);536for (FileSystemProvider provider: sl) {537try {538return provider.newFileSystem(path, env);539} catch (UnsupportedOperationException uoe) {540}541}542}543544throw new ProviderNotFoundException("Provider not found");545}546}547548549