JDK源码:File
Posted jdkSpring
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码:File相关的知识,希望对你有一定的参考价值。
Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。File对象代表磁盘中实际存在的文件和目录,File类实现了Serializable,表示可以被序列化。File类内部依赖于FileSystem,FileSystem为本地文件系统抽象打包私有抽象类。抽象出了一个 FileSystem 来表示文件系统,不同的操作系统通过继承该类实现各自的文件系统,比如 Windows操作系统则为 WinNTFileSystem,而 unix操作系统为 UnixFileStream.需要注意的一点是,WinNTFileSystem类和 UnixFileSystem类并不是在同一个 JDK 里面,也就是说它们是分开的,你只能在 Windows 版本的 JDK 中找到 WinNTFileSystem,而在 unix 版本的 JDK 中找到 UnixFileSystem,同样地,其他操作系统也有自己的文件系统实现类,由于此类方法较多,不一一列举,请看下面的代码注释。
类名
public class File implements Serializable, Comparable<File>
成员变量
File类的方法较多,这里只列出几个,下面会有整个类的注释。
File(String pathname)
File(String parent, String child)
list()
代码注释
public class File implements Serializable, Comparable<File>
{
/**
* 表示平台本地文件系统的file system对象.
*/
private static final FileSystem fs =
DefaultFileSystem.getFileSystem();
/**
* 此抽象路径名的规范化路径名字符串。
* 规范化路径名字符串使用默认名称分隔符,
* 不包含任何重复或冗余的分隔符.
*/
private final String path;
/**
* 指示文件路径状态的枚举类型
*/
private static enum PathStatus { INVALID, CHECKED };
/**
* 指示文件路径是否无效的标志
*/
private transient PathStatus status = null;
/**
* 检查文件的路径是否无效。
* 目前,对文件路径的检查是非常有限的,
* 它只包括Nul字符检查。
* 返回true意味着路径绝对无效/垃圾。
* 但返回false并不保证路径有效
*/
final boolean isInvalid() {
if (status == null) {
status =
(this.path.indexOf('u0000') < 0) ? PathStatus.CHECKED
: PathStatus.INVALID;
}
return status == PathStatus.INVALID;
}
/**
* 此抽象路径名前缀的长度,如果没有前缀,则为零
*/
private final transient int prefixLength;
/**
* 依赖于系统的默认分隔符字符
* 在linux下为 "/" ,windows为 "\"
*/
public static final char separatorChar = fs.getSeparator();
/**
* 默认分隔符,用字符串表示已方便使用
*/
public static final String separator = "" + separatorChar;
/**
* 分割连续路径的分隔符. This field is
* linux中为 ":" windows中为 ";"
*/
public static final char pathSeparatorChar = fs.getPathSeparator();
/**
* 分割连续路径的分隔符,用字符串表示已方便使用
*/
public static final String pathSeparator = "" + pathSeparatorChar;
/**
* 返回此路径名前缀的长度.
*/
int getPrefixLength() {
return prefixLength;
}
/* -- Constructors -- */
/**
* 指定路径和前缀长度创建File.
*/
private File(String pathname, int prefixLength) {
this.path = pathname;
this.prefixLength = prefixLength;
}
/**
* 内部构造函数,
* 参数顺序是为了区分public File(File parent, String child)方法
*/
private File(String child, File parent) {
assert parent.path != null;
assert (!parent.path.equals(""));
this.path = fs.resolve(parent.path, child);
this.prefixLength = parent.prefixLength;
}
/**
* 指定路径创建File
*/
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
/**
* 以父路径名字符串和子路径名字符串创建File对象
* 如果父路径为null,则以子路径创建File对象
* 如果子路径是绝对路径,
* 则会以系统相关的方式将其转换为相对路径名
*/
public File(String parent, String child) {
if (child == null) {
throw new NullPointerException();
}
if (parent != null) {
if (parent.equals("")) {
//根据父路径解析子路径名字符串
this.path = fs.resolve(fs.getDefaultParent(),
fs.normalize(child));
} else {
this.path = fs.resolve(fs.normalize(parent),
fs.normalize(child));
}
} else {
//将给定的路径名字符串转换为普通形式。
//如果字符串已经是正常形式,那么只需返回它
this.path = fs.normalize(child);
}
this.prefixLength = fs.prefixLength(this.path);
}
/**
* 用父路径名和子路径名创建File实例.
*/
public File(File parent, String child) {
if (child == null) {
throw new NullPointerException();
}
if (parent != null) {
if (parent.path.equals("")) {
//根据父路径解析子路径名字符串
this.path = fs.resolve(fs.getDefaultParent(),
fs.normalize(child));
} else {
this.path = fs.resolve(parent.path,
fs.normalize(child));
}
} else {
//将给定的路径名字符串转换为普通形式。
//如果字符串已经是正常形式,那么只需返回它
this.path = fs.normalize(child);
}
this.prefixLength = fs.prefixLength(this.path);
}
/**
* 通过给定的file:uri转换为抽象路径名创建File.
*
* file:URI的确切形式依赖于系统,因此此构造函数执行的转换也依赖于系统
* 如:new File(new URI("file:///c:/a.bat"))
* @since 1.4
*/
public File(URI uri) {
// Check our many preconditions
if (!uri.isAbsolute())
throw new IllegalArgumentException("URI is not absolute");
if (uri.isOpaque())
throw new IllegalArgumentException("URI is not hierarchical");
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
throw new IllegalArgumentException("URI scheme is not "file"");
if (uri.getAuthority() != null)
throw new IllegalArgumentException("URI has an authority component");
if (uri.getFragment() != null)
throw new IllegalArgumentException("URI has a fragment component");
if (uri.getQuery() != null)
throw new IllegalArgumentException("URI has a query component");
String p = uri.getPath();
if (p.equals(""))
throw new IllegalArgumentException("URI path component is empty");
// 如有必要,处理给定的URI路径字符串
p = fs.fromURIPath(p);
//替换成系统的分隔符
if (File.separatorChar != '/')
p = p.replace('/', File.separatorChar);
//将给定的路径名字符串转换为普通形式。
//如果字符串已经是正常形式,那么只需返回它
this.path = fs.normalize(p);
this.prefixLength = fs.prefixLength(this.path);
}
/**
* 返回文件或目录的名称
*/
public String getName() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) return path.substring(prefixLength);
return path.substring(index + 1);
}
/**
*返回父目录的路径名字符串.
*如果没有就返回null
*/
public String getParent() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) {
if ((prefixLength > 0) && (path.length() > prefixLength))
return path.substring(0, prefixLength);
return null;
}
return path.substring(0, index);
}
/**
* 返回父目录的File对象
* @since 1.2
*/
public File getParentFile() {
String p = this.getParent();
if (p == null) return null;
return new File(p, this.prefixLength);
}
/**
* 返回目录或文件的路径
*/
public String getPath() {
return path;
}
/**
* 测试路径名是否为绝对路径名.
*/
public boolean isAbsolute() {
return fs.isAbsolute(this);
}
/**
* 返回绝对路径名字符串.
*
* 如果这个抽象路径名已经是绝对路径名,
* 那么路径名字符串将被简单地返回,就像由getPath方法返回一样。
* 如果此抽象路径名是空的抽象路径名,
* 则返回由系统属性user.dir命名的当前用户目录的路径名字符串。
* 否则,将以系统相关的方式解析此路径名。
* 在UNIX系统上,相对路径名通过对当前用户目录进行解析而成为绝对路径名。
* 在Microsoft Windows系统上,相对路径名是绝对的,
* 方法是根据路径名命名的驱动器的当前目录(如果有)进行解析;
* 如果没有,则根据当前用户目录进行解析
*/
public String getAbsolutePath() {
return fs.resolve(this);
}
/**
* 返回绝对路径的File对象.
* @since 1.2
*/
public File getAbsoluteFile() {
//获取绝对路径
String absPath = getAbsolutePath();
return new File(absPath, fs.prefixLength(absPath));
}
/**
* 返回规范的路径名.
*
* 规范路径名既绝对又唯一。
* 规范形式的精确定义依赖于系统
* 如果需要,此方法首先将此路径名转换为绝对形式
* 然后以系统相关的方式将其映射到其唯一形式
* 并修改驱动器大小写(Windows下)
* File file = new File("d:");
* File file1 = new File(file, "jdk_s_d");
* System.out.println(file1.getCanonicalPath());
* 输出:D:jdk_s_d
* @since JDK1.1
*/
public String getCanonicalPath() throws IOException {
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.canonicalize(fs.resolve(this));
}
/**
* 返回规范的路径File对象
* @since 1.2
*/
public File getCanonicalFile() throws IOException {
String canonPath = getCanonicalPath();
return new File(canonPath, fs.prefixLength(canonPath));
}
//转换路径为URI格式时调用,添加斜线
private static String slashify(String path, boolean isDirectory) {
String p = path;
if (File.separatorChar != '/')
p = p.replace(File.separatorChar, '/');
if (!p.startsWith("/"))
p = "/" + p;
if (!p.endsWith("/") && isDirectory)
p = p + "/";
return p;
}
/**
* 已弃用
*/
public URL toURL() throws MalformedURLException {
if (isInvalid()) {
throw new MalformedURLException("Invalid file path");
}
return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
}
/**
* 获取文件的URI.
* URI的确切形式取决于系统。
* 如果可以确定这个路径名所表示的文件是一个目录,
* 那么生成的URI将以斜线结尾
* File file = new File("d:");
* File file1 = new File(file, "jdk_s_d");
* System.out.println(file1.toURI());
* 输出:file:/d:/jdk_s_d/
* @since 1.4
*/
public URI toURI() {
try {
File f = getAbsoluteFile();
String sp = slashify(f.getPath(), f.isDirectory());
if (sp.startsWith("//"))
sp = "//" + sp;
return new URI("file", null, sp, null);
} catch (URISyntaxException x) {
throw new Error(x); // Can't happen
}
}
/* -- Attribute accessors -- */
/**
* 文件是否可读
*/
public boolean canRead() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_READ);
}
/**
* 文件是否可写
*/
public boolean canWrite() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}
/**
* 文件是否存在
*/
public boolean exists() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
/**
* 文件是否是目录
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
!= 0);
}
/**
* 是否是文件
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}
/**
* 是否是隐藏文件
* @since 1.2
*/
public boolean isHidden() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
}
/**
* 返回文件上次修改的时间
* File file = new File("d:");
* File file1 = new File(file, "jdk_s_d");
* System.out.println(file1.lastModified());
* 输出:1577975690211
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLastModifiedTime(this);
}
/**
* 返回此抽象路径名表示的文件长度。
* 如果此路径名表示目录,则返回值不定
* File file1 = new File("d:\jdk_s_d\out.txt");
* System.out.println(file1.length());
* 输出:134 //测试的out.txt文件大小为134字节
*/
public long length() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLength(this);
}
/**
* 创建一个新的空文件,该文件由这个指定的路径名命名,
* 当且仅当这个名称的文件不存在时。
* 如果文件不存在,则检查文件的存在和文件的创建,
* 这是对可能影响文件的所有其他文件系统活动的原子操作.
* @since 1.2
*/
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.createFileExclusively(path);
}
/**
* 删除此路径名表示的文件或目录。
* 如果此路径名表示目录,则目录必须为空才能删除.
*/
public boolean delete() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return false;
}
return fs.delete(this);
}
/**
* 请求在虚拟机终止时删除此抽象路径名表示的文件或目录。
* 文件(或目录)按注册的相反顺序删除。
* 调用此方法删除已注册删除的文件或目录无效。
* 只有在Java语言规范定义的虚拟机正常终止时才会尝试删除
* @since 1.2
*/
public void deleteOnExit() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return;
}
DeleteOnExitHook.add(path);
}
/**
* 返回一个字符串数组,用于路径名所表示的目录中的文件和目录.
* File file1 = new File("d:\jdk_s_d");
* String[] list = file1.list();
* for (String f : list) {
* System.out.println(f);
* }
* 输出jdk_s_d下所有文件和目录
*/
public String[] list() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return null;
}
return fs.list(this);
}
/**
* 返回一个字符串数组,
* 用于命名此路径名所表示的目录中满足指定筛选器的文件和目录
* File file1 = new File("d:\jdk_s_d");
* String[] list = file1.list(new FilenameFilter() {
* @Override
* public boolean accept(File dir, String name) {
* //列出文件名包含"InputStream"字符串的文件名
* return name.contains("InputStream");
* }
* });
* for (String f : list) {
* System.out.println(f);
* }
*/
public String[] list(FilenameFilter filter) {
String names[] = list();
if ((names == null) || (filter == null)) {
return names;
}
List<String> v = new ArrayList<>();
for (int i = 0 ; i < names.length ; i++) {
if (filter.accept(this, names[i])) {
v.add(names[i]);
}
}
return v.toArray(new String[v.size()]);
}
/**
* 返回一个File数组,表示路径名所表示的目录中的文件.
*
* 如果此抽象路径名不表示目录,则此方法返回null。
* 否则将返回一个File对象数组,
* 该数组中每个文件或目录对应一个对象。
* 结果中不包括表示目录本身和目录父目录的路径名。
* @since 1.2
*/
public File[] listFiles() {
//路径下所有文件名
String[] ss = list();
if (ss == null) return null;
int n = ss.length;
//创建File对象数组
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = new File(ss[i], this);
}
return fs;
}
/**返回过滤后的File数组
*/
public File[] listFiles(FilenameFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
for (String s : ss)
if ((filter == null) || filter.accept(this, s))
files.add(new File(s, this));
return files.toArray(new File[files.size()]);
}
/**
* 返回过滤后的File数组
* File file1 = new File("d:\jdk_s_d");
* File[] list = file1.listFiles(new FileFilter() {
* @Override
* public boolean accept(File pathname) {
* return false;
* }
*});
*/
public File[] listFiles(FileFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
for (String s : ss) {
File f = new File(s, this);
if ((filter == null) || filter.accept(f))
files.add(f);
}
return files.toArray(new File[files.size()]);
}
/**
* 创建一个目录.
*/
public boolean mkdir() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.createDirectory(this);
}
/**
* 创建由这个路径名命名的目录,
* 包括任何必要但不存在的父目录。
* 注意,如果这个操作失败,
* 它可能已经成功地创建了一些必要的父目录.
*/
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());
}
/**
*重命名此路径名表示的文件
*File file1 = new File("d:\jdk_a_d");
*file1.renameTo(new File("d:\jdk_s_d"));
*将文件名jdk_a_d重命名为jdk_s_d
*/
public boolean renameTo(File dest) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
security.checkWrite(dest.path);
}
if (dest == null) {
throw new NullPointerException();
}
if (this.isInvalid() || dest.isInvalid()) {
return false;
}
return fs.rename(this, dest);
}
/**
* 设置此文件或目录的上次修改时间.
* @since 1.2
*/
public boolean setLastModified(long time) {
if (time < 0) throw new IllegalArgumentException("Negative time");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setLastModifiedTime(this, time);
}
/**
* 设置文件只读
* @since 1.2
*/
public boolean setReadOnly() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setReadOnly(this);
}
/**
* 设置文件可写
* @param 如果true,则写入权限仅适用于所有者的写入权限;
* 否则,它适用于所有人。
* 如果底层文件系统无法区分所有者的写权限和其他人的写权限,
* 那么该权限将应用于所有人,而不考虑此值
* @since 1.6
*/
public boolean setWritable(boolean writable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
}
/**
* 设置文件可写
*
* @since 1.6
*/
public boolean setWritable(boolean writable) {
return setWritable(writable, true);
}
/**
* 设置文件可读
* @since 1.6
*/
public boolean setReadable(boolean readable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
}
/**
* 设置文件可读
* @since 1.6
*/
public boolean setReadable(boolean readable) {
return setReadable(readable, true);
}
/**
* 设置文件可执行
* @since 1.6
*/
public boolean setExecutable(boolean executable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
}
/**
* 设置文件可执行
* @since 1.6
*/
public boolean setExecutable(boolean executable) {
return setExecutable(executable, true);
}
/**
* 文件是否可执行
* @since 1.6
*/
public boolean canExecute() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExec(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
}
/* -- Filesystem interface -- */
/**
* 列出可用的文件系统根目录.
*/
public static File[] listRoots() {
return fs.listRoots();
}
/**
* 返回按此路径名命名的分区的大小.
* @since 1.6
*/
public long getTotalSpace() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_TOTAL);
}
/**
* 返回分区中未分配的字节数
*
* @since 1.6
*/
public long getFreeSpace() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_FREE);
}
/**
* 返回分区上此虚拟机可用的字节数
* @since 1.6
*/
public long getUsableSpace() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
/* -- Temporary files -- */
private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
private static final File tmpdir = new File(AccessController
.doPrivileged(new GetPropertyAction("java.io.tmpdir")));
static File location() {
return tmpdir;
}
// file name generation
private static final SecureRandom random = new SecureRandom();
static File generateFile(String prefix, String suffix, File dir)
throws IOException
{
long n = random.nextLong();
if (n == Long.MIN_VALUE) {
n = 0; // corner case
} else {
n = Math.abs(n);
}
// Use only the file name from the supplied prefix
prefix = (new File(prefix)).getName();
String name = prefix + Long.toString(n) + suffix;
File f = new File(dir, name);
if (!name.equals(f.getName()) || f.isInvalid()) {
if (System.getSecurityManager() != null)
throw new IOException("Unable to create temporary file");
else
throw new IOException("Unable to create temporary file, " + f);
}
return f;
}
}
/**
* <p> 在指定目录中创建新的空文件,使用给定的前缀和后缀字符串生成其名称:
*此方法仅提供临时文件工具的一部分。
*若要安排由此方法创建的文件自动删除,请使用deleteOnExit方法
* @since 1.2
*/
public static File createTempFile(String prefix, String suffix,
File directory)
throws IOException
{
if (prefix.length() < 3)
throw new IllegalArgumentException("Prefix string too short");
if (suffix == null)
suffix = ".tmp";
File tmpdir = (directory != null) ? directory
: TempDirectory.location();
SecurityManager sm = System.getSecurityManager();
File f;
do {
f = TempDirectory.generateFile(prefix, suffix, tmpdir);
if (sm != null) {
try {
sm.checkWrite(f.getPath());
} catch (SecurityException se) {
// don't reveal temporary directory location
if (directory == null)
throw new SecurityException("Unable to create temporary file");
throw se;
}
}
} while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0);
if (!fs.createFileExclusively(f.getPath()))
throw new IOException("Unable to create temporary file");
return f;
}
/**
* 创建临时文件
*/
public static File createTempFile(String prefix, String suffix)
throws IOException
{
return createTempFile(prefix, suffix, null);
}
/* -- Basic infrastructure -- */
/**
* 比较两个File路径名,此方法定义的顺序取决于底层系统
* 在UNIX系统中,字母大小写在比较路径名时非常重要;
* 而在Microsoft Windows系统中则不是。
* @since 1.2
*/
public int compareTo(File pathname) {
return fs.compare(this, pathname);
}
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof File)) {
return compareTo((File)obj) == 0;
}
return false;
}
public int hashCode() {
return fs.hashCode(this);
}
/**
* 返回路径名
*/
public String toString() {
return getPath();
}
/**
* 调用WriteObject以保存此文件名。
* 分隔符也将被保存,
* 以便在路径在其他主机类型上重新组合时可以替换它.
*/
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
s.defaultWriteObject();
s.writeChar(separatorChar); // Add the separator character
}
/**
* 调用readObject以还原此文件名。
* 读取原始分隔符字符。
*/
private synchronized void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException
{
ObjectInputStream.GetField fields = s.readFields();
String pathField = (String)fields.get("path", null);
char sep = s.readChar(); // read the previous separator char
if (sep != separatorChar)
pathField = pathField.replace(sep, separatorChar);
String path = fs.normalize(pathField);
UNSAFE.putObject(this, PATH_OFFSET, path);
UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET, fs.prefixLength(path));
}
private static final long PATH_OFFSET;
private static final long PREFIX_LENGTH_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
try {
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
PATH_OFFSET = unsafe.objectFieldOffset(
File.class.getDeclaredField("path"));
PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset(
File.class.getDeclaredField("prefixLength"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 301077366599181567L;
// -- Integration with java.nio.file --
private volatile transient Path filePath;
public Path toPath() {
Path result = filePath;
if (result == null) {
synchronized (this) {
result = filePath;
if (result == null) {
result = FileSystems.getDefault().getPath(path);
filePath = result;
}
}
}
return result;
}
}
以上是关于JDK源码:File的主要内容,如果未能解决你的问题,请参考以下文章
idea 导入 jdk源码 解决compile code 后阅读jdk 源码