8154077: (fs) Reduce number of file system classes loaded during startup

Reviewed-by: bpb, chegar
This commit is contained in:
Alan Bateman 2016-04-13 14:29:25 +01:00
parent 87c6cee72e
commit 33a3b1cdf0
9 changed files with 156 additions and 8 deletions

View File

@ -161,7 +161,9 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
Java_sun_nio_fs_UnixNativeDispatcher_access0;
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;

View File

@ -138,7 +138,9 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
Java_sun_nio_fs_UnixNativeDispatcher_access0;
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;

View File

@ -138,7 +138,9 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
Java_sun_nio_fs_UnixNativeDispatcher_access0;
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;

View File

@ -77,6 +77,8 @@ import java.util.function.BiPredicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import sun.nio.fs.AbstractFileSystemProvider;
/**
* This class consists exclusively of static methods that operate on files,
* directories, or other types of files.
@ -2193,6 +2195,12 @@ 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();
} catch (IOException ioe) {
@ -2230,6 +2238,12 @@ 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();
} catch (IOException ioe) {
@ -2385,6 +2399,12 @@ public final class Files {
* @see #notExists
*/
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);

View File

@ -25,7 +25,9 @@
package sun.nio.fs;
import java.nio.file.*;
import java.nio.file.Path;
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.io.IOException;
import java.util.Map;
@ -34,7 +36,7 @@ import java.util.Map;
* Base implementation class of FileSystemProvider
*/
abstract class AbstractFileSystemProvider extends FileSystemProvider {
public abstract class AbstractFileSystemProvider extends FileSystemProvider {
protected AbstractFileSystemProvider() { }
/**
@ -107,4 +109,49 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
public final boolean deleteIfExists(Path file) throws IOException {
return implDelete(file, false);
}
/**
* Tests whether a file is a directory.
*
* @return {@code true} if the file is a directory; {@code false} if
* the file does not exist, is not a directory, or it cannot
* be determined if the file is a directory or not.
*/
public boolean isDirectory(Path file) {
try {
return readAttributes(file, BasicFileAttributes.class).isDirectory();
} catch (IOException ioe) {
return false;
}
}
/**
* Tests whether a file is a regular file with opaque content.
*
* @return {@code true} if the file is a regular file; {@code false} if
* the file does not exist, is not a regular file, or it
* cannot be determined if the file is a regular file or not.
*/
public boolean isRegularFile(Path file) {
try {
return readAttributes(file, BasicFileAttributes.class).isRegularFile();
} catch (IOException ioe) {
return false;
}
}
/**
* Checks the existence of a file.
*
* @return {@code true} if the file exists; {@code false} if the file does
* not exist or its existence cannot be determined.
*/
public boolean exists(Path file) {
try {
checkAccess(file);
return true;
} catch (IOException ioe) {
return false;
}
}
}

View File

@ -499,6 +499,29 @@ public abstract class UnixFileSystemProvider
}
}
@Override
public final boolean isDirectory(Path obj) {
UnixPath file = UnixPath.toUnixPath(obj);
file.checkRead();
int mode = UnixNativeDispatcher.stat(file);
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
}
@Override
public final boolean isRegularFile(Path obj) {
UnixPath file = UnixPath.toUnixPath(obj);
file.checkRead();
int mode = UnixNativeDispatcher.stat(file);
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
}
@Override
public final boolean exists(Path obj) {
UnixPath file = UnixPath.toUnixPath(obj);
file.checkRead();
return UnixNativeDispatcher.exists(file);
}
/**
* Returns a {@code FileTypeDetector} for this platform.
*/

View File

@ -296,6 +296,23 @@ class UnixNativeDispatcher {
private static native void stat0(long pathAddress, UnixFileAttributes attrs)
throws UnixException;
/**
* stat(const char* path, struct stat* buf)
*
* @return st_mode (file type and mode) or 0 if an error occurs.
*/
static int stat(UnixPath path) {
NativeBuffer buffer = copyToNativeBuffer(path);
try {
return stat1(buffer.address());
} finally {
buffer.release();
}
}
private static native int stat1(long pathAddress);
/**
* lstat(const char* path, struct stat* buf)
*/
@ -458,6 +475,22 @@ class UnixNativeDispatcher {
}
private static native void access0(long pathAddress, int amode) throws UnixException;
/**
* access(constant char* path, F_OK)
*
* @return true if the file exists, false otherwise
*/
static boolean exists(UnixPath path) {
NativeBuffer buffer = copyToNativeBuffer(path);
try {
return exists0(buffer.address());
} finally {
buffer.release();
}
}
private static native boolean exists0(long pathAddress);
/**
* struct passwd *getpwuid(uid_t uid);
*

View File

@ -114,12 +114,9 @@ class UnixUriUtils {
// trailing slash if directory
if (sb.charAt(sb.length()-1) != '/') {
try {
if (UnixFileAttributes.get(up, true).isDirectory())
sb.append('/');
} catch (UnixException x) {
// ignore
}
int mode = UnixNativeDispatcher.stat(up);
if ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR)
sb.append('/');
}
try {

View File

@ -483,6 +483,20 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
}
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_stat1(JNIEnv* env, jclass this, jlong pathAddress) {
int err;
struct stat64 buf;
const char* path = (const char*)jlong_to_ptr(pathAddress);
RESTARTABLE(stat64(path, &buf), err);
if (err == -1) {
return 0;
} else {
return (jint)buf.st_mode;
}
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
jlong pathAddress, jobject attrs)
@ -897,6 +911,14 @@ Java_sun_nio_fs_UnixNativeDispatcher_access0(JNIEnv* env, jclass this,
}
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_exists0(JNIEnv* env, jclass this, jlong pathAddress) {
int err;
const char* path = (const char*)jlong_to_ptr(pathAddress);
RESTARTABLE(access(path, F_OK), err);
return (err == 0) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
jlong pathAddress, jobject attrs)