源码解读之File
文件和目录路径名的抽象表示形式。
我们知道,对于不同的操作系统,文件路径的描述是不同的
比如
windows平台:用\
linux平台:用/
四个构造方法
API:
文件自身属性读取
创建文件/目录基本操作
文件/目录 列表读取
文件权限访问以及文件信息设置
其他
FileSystem简介
File中有一个变量fs 类型为FileSystem
compareTo方法依赖于他
而equals方法又依赖compareTo
hashCode也是依赖他
所以说:
compareTo equals hashCode 都依赖于 FileSystem fs
其实你在回头看看整个File文件中,很多个地方都出现了fs的身影
FileSystem到底是什么?
操作系统有各自的文件系统,这些文件系统又存在很多差异,而Java 因为是跨平台的,所以它必须要统一处理这些不同平台文件系统之间的差异,才能往上提供统一的入口。
说白了又是接口来实现统一,不同的操作系统实现这个接口,就可以提供统一的表现形式
FileSystem是一个抽象类
windows下的实现类为:WinNTFileSystem,在IDE中可以直接找到
可能你只是找到了一个WinNTFileSystem,只有一个要接口还有什么意思?
如果你目前只看到了一个WinNTFileSystem 那说明你在Windows下
WinNTFileSystem类 和 UnixFileSystem类并不是在同一个 JDK 里面,也就是说它们是分开的
你只能在 Windows 版本的 JDK 中找到 WinNTFileSystem,而在 Linux 版本的 JDK 中找到 UnixFileSystem
同样地,其他操作系统也有自己的文件系统实现类。
接下来大致的看下WinNTFileSystem
属性
private final char slash;//斜杠符号 private final char altSlash;//与slash相反的斜杠 private final char semicolon;//分号 private static String[] driveDirCache = new String[26];//表示驱动盘目录缓存 private ExpiringCache cache = new ExpiringCache();//用于缓存标准路径 private ExpiringCache prefixCache = new ExpiringCache();//用于缓存标准路径前缀
其实slash就是名称分隔符
semicolon就是路径分隔符
构造方法中根据系统变量对文件分隔符和路径分隔符进行初始化
isSlash 和 isLetter都非常简单,简单的判断
判断是否以slash 开头,是的话直接返回,不是的话,给他加一个
getSeparator 和 getPathSeparator 就是File中分隔符的来处
路径的标准化
不光标准化,前面还提到了规范化路径 File中有方法getCanonicalFile getCanonicalPath
他们到底都是在说什么事情呢
先说下标准化,看一个例子
虽然看起来很奇怪,但是不影响程序运行
我们此时可以用比较通俗的话来描述这个情况
我们给出来了一个乱七八糟的路径,最终路径按照当前文件系统的规则,进行了解析,
去除了不必要的分隔符 或者可能把错误的分隔符进行替换等按照一定的规则
整理出来一个合理的路径,这就是标准化
|
debug 看下File的构造方法 就知道了
最终他帮我们正确的解析了路径,这就是标准化
可以看得出来,标准化,借助的仍旧是fs 也就是FileSystem
在WinNTFileSystem 中的normalize方法就是标准化路径的一个对外接口
他还有两个相关的private方法,用于处理细节
方法的具体过程,到底是怎么处理的,有兴趣的同学可以继续深挖以下
仔细看下注释也可理解一二
一个标准的win32路径名,不能包括重复的名称分隔符(斜杠) UNC除外 ,也不能以名称分隔符(斜杠)结束
可能是一个空的String
规范化Win32路径名具有便捷的特点:前缀的长度几乎唯一地标识了路径的类型
无论它是绝对的还是相对的
0,1,2,3是分类说明
如同上面标准化描述的一样,前缀的长度对于标准化很有用,这个方法经常被使用
规范化路径 File中有方法getCanonicalFile getCanonicalPath,规范化,借助的仍旧是fs 也就是FileSystem