mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8283335: Add exists and readAttributesIfExists methods to FileSystemProvider
Reviewed-by: alanb
This commit is contained in:
parent
c45d613faa
commit
d48694d0f3
13 changed files with 577 additions and 175 deletions
|
@ -80,7 +80,6 @@ import java.util.stream.StreamSupport;
|
|||
import jdk.internal.util.ArraysSupport;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
import sun.nio.cs.UTF_8;
|
||||
import sun.nio.fs.AbstractFileSystemProvider;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods that operate on files,
|
||||
|
@ -1594,7 +1593,7 @@ public final class Files {
|
|||
byte[] buffer1 = new byte[BUFFER_SIZE];
|
||||
byte[] buffer2 = new byte[BUFFER_SIZE];
|
||||
try (InputStream in1 = Files.newInputStream(path);
|
||||
InputStream in2 = Files.newInputStream(path2);) {
|
||||
InputStream in2 = Files.newInputStream(path2)) {
|
||||
long totalRead = 0;
|
||||
while (true) {
|
||||
int nRead1 = in1.readNBytes(buffer1, 0, BUFFER_SIZE);
|
||||
|
@ -2310,14 +2309,10 @@ public final class Files {
|
|||
* method denies read access to the file.
|
||||
*/
|
||||
public static boolean isDirectory(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).isDirectory(path);
|
||||
}
|
||||
|
||||
try {
|
||||
return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
|
||||
var attrs = provider(path)
|
||||
.readAttributesIfExists(path, BasicFileAttributes.class, options);
|
||||
return (attrs != null) && attrs.isDirectory();
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2353,14 +2348,10 @@ public final class Files {
|
|||
* method denies read access to the file.
|
||||
*/
|
||||
public static boolean isRegularFile(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).isRegularFile(path);
|
||||
}
|
||||
|
||||
try {
|
||||
return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
|
||||
var attrs = provider(path)
|
||||
.readAttributesIfExists(path, BasicFileAttributes.class, options);
|
||||
return (attrs != null) && attrs.isRegularFile();
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2502,7 +2493,7 @@ public final class Files {
|
|||
* the path to the file to test
|
||||
* @param options
|
||||
* options indicating how symbolic links are handled
|
||||
* .
|
||||
*
|
||||
* @return {@code true} if the file exists; {@code false} if the file does
|
||||
* not exist or its existence cannot be determined.
|
||||
*
|
||||
|
@ -2515,27 +2506,7 @@ public final class Files {
|
|||
* @see FileSystemProvider#checkAccess
|
||||
*/
|
||||
public static boolean exists(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).exists(path);
|
||||
}
|
||||
|
||||
try {
|
||||
if (followLinks(options)) {
|
||||
provider(path).checkAccess(path);
|
||||
} else {
|
||||
// attempt to read attributes without following links
|
||||
readAttributes(path, BasicFileAttributes.class,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
}
|
||||
// file exists
|
||||
return true;
|
||||
} catch (IOException x) {
|
||||
// does not exist or unable to determine if file exists
|
||||
return false;
|
||||
}
|
||||
|
||||
return provider(path).exists(path, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1170,4 +1170,122 @@ public abstract class FileSystemProvider {
|
|||
public abstract void setAttribute(Path path, String attribute,
|
||||
Object value, LinkOption... options)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Tests whether a file exists. This method works in exactly the
|
||||
* manner specified by the {@link Files#exists(Path, LinkOption...)} method.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation of this method invokes the
|
||||
* {@link #checkAccess(Path, AccessMode...)} method when symbolic links
|
||||
* are followed. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS}
|
||||
* is present then symbolic links are not followed and the method
|
||||
* {@link #readAttributes(Path, Class, LinkOption...)} is called
|
||||
* to determine whether a file exists.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file to test
|
||||
* @param options
|
||||
* options indicating how symbolic links are handled
|
||||
*
|
||||
* @return {@code true} if the file exists; {@code false} if the file does
|
||||
* not exist or its existence cannot be determined.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* In the case of the default provider, the {@link
|
||||
* SecurityManager#checkRead(String)} is invoked to check
|
||||
* read access to the file.
|
||||
*
|
||||
* @since 20
|
||||
*/
|
||||
public boolean exists(Path path, LinkOption... options) {
|
||||
try {
|
||||
if (followLinks(options)) {
|
||||
this.checkAccess(path);
|
||||
} else {
|
||||
// attempt to read attributes without following links
|
||||
readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
|
||||
}
|
||||
// file exists
|
||||
return true;
|
||||
} catch (IOException x) {
|
||||
// does not exist or unable to determine if file exists
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file's attributes as a bulk operation if it exists.
|
||||
*
|
||||
* <p> The {@code type} parameter is the type of the attributes required
|
||||
* and this method returns an instance of that type if supported. All
|
||||
* implementations support a basic set of file attributes and so invoking
|
||||
* this method with a {@code type} parameter of {@code
|
||||
* BasicFileAttributes.class} will not throw {@code
|
||||
* UnsupportedOperationException}.
|
||||
*
|
||||
* <p> The {@code options} array may be used to indicate how symbolic links
|
||||
* are handled for the case that the file is a symbolic link. By default,
|
||||
* symbolic links are followed and the file attribute of the final target
|
||||
* of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
|
||||
* NOFOLLOW_LINKS} is present then symbolic links are not followed.
|
||||
*
|
||||
* <p> It is implementation specific if all file attributes are read as an
|
||||
* atomic operation with respect to other file system operations.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation of this method invokes the
|
||||
* {@link #readAttributes(Path, Class, LinkOption...)} method
|
||||
* to read the file's attributes.
|
||||
*
|
||||
* @param <A>
|
||||
* The {@code BasicFileAttributes} type
|
||||
* @param path
|
||||
* the path to the file
|
||||
* @param type
|
||||
* the {@code Class} of the file attributes required
|
||||
* to read
|
||||
* @param options
|
||||
* options indicating how symbolic links are handled
|
||||
*
|
||||
* @return the file attributes or null if the file does not exist
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* if an attributes of the given type are not supported
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
* @throws SecurityException
|
||||
* In the case of the default provider, a security manager is
|
||||
* installed, its {@link SecurityManager#checkRead(String) checkRead}
|
||||
* method is invoked to check read access to the file. If this
|
||||
* method is invoked to read security sensitive attributes then the
|
||||
* security manager may be invoked to check for additional permissions.
|
||||
*
|
||||
* @since 20
|
||||
*/
|
||||
public <A extends BasicFileAttributes> A readAttributesIfExists(Path path,
|
||||
Class<A> type,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
return readAttributes(path, type, options);
|
||||
} catch (NoSuchFileException ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean followLinks(LinkOption... options) {
|
||||
boolean followLinks = true;
|
||||
for (LinkOption opt: options) {
|
||||
if (opt == LinkOption.NOFOLLOW_LINKS) {
|
||||
followLinks = false;
|
||||
continue;
|
||||
}
|
||||
if (opt == null)
|
||||
throw new NullPointerException();
|
||||
throw new AssertionError("Should not get here");
|
||||
}
|
||||
return followLinks;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue