当前位置: 移动技术网 > IT编程>开发语言>Java > [二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介

[二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介

2018年09月08日  | 移动技术网IT编程  | 我要评论

78439小游戏娜米,乐吧薯片非你莫属,山柳村寡妇的情史

file类
文件和目录路径名的抽象表示形式。
我们知道,对于不同的操作系统,文件路径的描述是不同的
比如
windows平台:用\
linux平台:用/
 
file是java为了这一概念提供的抽象描述,与系统无关的视图
抽象路径名有两个组件:
1.可选的与系统有关的前缀  字符串   比如盘符,"/" 表示 unix 中的根目录,"\\\\" 表示 microsoft windows unc 路径名
2.零个或者多个  字符串  名称 序列
 
第一个名称是 目录名,第一个名称之后每个名称表示一个目录,最后一个名称既可以是目录,也可以是名称
空 抽象路径名没有前缀和名称序列
注意:
既然最后一个名称可以是目录,也可以是文件名称,那么file 并不一定就是一个文件,也可以是一个文件路径,也就是目录

构造方法

java中使用file来抽象表示 文件/目录这一个概念
也就是在java中,想要表示一个文件,构造一个file对象即可
构造方法
file(file parent, string child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 file 实例。
file(string pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 file 实例。
file(string parent, string child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 file 实例。
file(uri uri)
通过将给定的 file: uri 转换为一个抽象路径名来创建一个新的 file 实例。
 
通过路径构造一个file,是最自然地做法
 
file(file parent, string child)根据参数file的路径和child字符串进行组合
file(string parent, string child)根据参数 parent字符串和child字符串组合
本质上也就还是路径,不过很显然,拼接 child 就可以进行创建子目录
 
uri是统一资源标识符,将文件转换成一个链接,可以网络访问 ,通过这个uri 也可以用来生成文件
 
new file只是在java中描述这么一个文件,是否真的存在? 你还需要进行去验证,只是一个虚拟的描述符
file file = new file("d:\\testfile");//file就是对这个路径的一个描述,那么是否真的存在? 你还需要进行去验证

名称与路径的分隔符

另外file 中还包括两个分隔符
目录分隔符  名称分隔符的两种形式  char 和 string
separatorchar
public static final char separatorchar
与系统有关的默认名称分隔符。
此字段被初始化为包含系统属性 file.separator 值的第一个字符。
在 unix 系统上,此字段的值为 '/';在 microsoft windows 系统上,它为 '\\'。
separator
public static final string separator
与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即 separatorchar。
pathseparatorchar
public static final char pathseparatorchar
与系统有关的路径分隔符。
此字段被初始为包含系统属性 path.separator 值的第一个字符。
此字符用于分隔以路径列表 形式给定的文件序列中的文件名。
在 unix 系统上,此字段为 ':';在  microsoft windows 系统上,它为 ';'。
pathseparator
public static final string pathseparator
与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
此字符串只包含一个字符,即 pathseparatorchar。 

file api分类

file既可能是目录,也可能是文件
那么,他必然提供了文件和目录的一些基本常见操作
按照文件的属性以及相关操作对api进行分类
 
文件自身属性读取
getname()
getparent()
getparentfile()
getpath()
ishidden()
lastmodified()
length()
isabsolute()
isdirectory()
isfile()
exists()
getabsolutefile()
getabsolutepath()
getcanonicalfile()
getcanonicalpath()
getfreespace()
gettotalspace()
getusablespace()
创建文件/目录基本操作       
mkdir()
mkdirs()
delete()
deleteonexit()
renameto(file)
createtempfile(string, string)
createtempfile(string, string, file)
createnewfile()
文件/目录 列表读取
listroots()
list()
list(filenamefilter)
listfiles()
listfiles(filefilter)
listfiles(filenamefilter)
文件权限访问以及文件信息设置
canexecute()
canread()
canwrite()
 
setexecutable(boolean)
setexecutable(boolean, boolean)
setreadable(boolean)
setreadable(boolean, boolean)
setreadonly()
setwritable(boolean)
setwritable(boolean, boolean)
setlastmodified(long)
其他
topath()
tostring()
touri()
 
equals(object)
compareto(file)
hashcode()
 

file api详解

 
测试:

file相关的基础信息属性

public string getname() 返回由此抽象路径名表示的文件或目录的名称。
该名称是路径名名称序列中的最后一个名称。如果路径名名称序列为空,则返回空字符串。
测试信息: getname():  cccc.txt
public string getparent() 返回此抽象路径名父目录的路径名字符串;
如果此路径名没有指定父目录,则返回 null。
getparent():  d:\testfile
public file getparentfile() public string getparent() 的file形式,等同于new file(getparent())
public string getpath() 将此抽象路径名转换为一个路径名字符串。
所得字符串使用  默认名称分隔符  分隔名称序列中的名称。 
 
一个file用于描述一个抽象路径名
这个抽象路径名(file) 的名称 name为  路径名名称序列中的最后一个名称 
这个抽象路径名(file) 的父 parent为  路径名名称序列中的除了最后一个名称以外的所有 
这个抽象路径名(file) 的路径path为  路径名名称序列中所有的名称,只不过使用默认的的名称分隔符分割
 
 
 
public boolean ishidden() 是否隐藏文件
测试此抽象路径名指定的文件是否是一个隐藏文件。
隐藏 的具体定义与系统有关
public long lastmodified()
long 毫秒数
表示文件最后一次被修改的时间的 long 值,
用与时间点(1970 年 1 月 1 日,00:00:00 gmt)之间的毫秒数表示;
如果该文件不存在,或者发生 i/o 错误,则返回 0l
public long length() 长度,字节
返回由此抽象路径名表示的文件的长度。
如果此路径名表示一个目录,则返回值是不确定的。
此抽象路径名表示的文件的长度,以字节为单位;
如果文件不存在,则返回 0l。
对于表示特定于系统的实体(比如设备或管道)的路径名,某些操作系统可能返回 0l。
public boolean isabsolute()
是否绝对路径
测试此抽象路径名是否为绝对路径名。绝对路径名的定义与系统有关。
在 unix 系统上,如果路径名的前缀是 "/",那么该路径名是绝对路径名。
在 microsoft windows 系统上,
如果路径名的前缀是后跟 "\\" 的盘符,或者是 "\\\\",那么该路径名是绝对路径名。
public boolean isdirectory() 当且仅当此抽象路径名表示的文件存在且 是一个目录时,返回 true;否则返回 false 
public boolean isfile() 当且仅当此抽象路径名表示的文件存在且 是一个标准文件时,返回 true;否则返回 false
public boolean exists() 当且仅当此抽象路径名表示的文件或目录存在时,返回 true;否则返回 false 
public string getabsolutepath() 绝对路径名字符串,它与此抽象路径名表示相同的文件或目录
public file getabsolutefile()
绝对    抽象路径名,它与此抽象路径名表示相同的文件或目录  相当于new file(this.getabsolutepath())
 
 
规范路径名是绝对路径名,并且是惟一的。规范路径名的准确定义与系统有关。
如有必要,此方法首先将路径名转换为绝对路径名,这与调用 getabsolutepath() 方法的效果一样,然后用与系统相关的方式将它映射到其惟一路径名。
这通常涉及到从路径名中移除多余的名称(比如 "." 和 "..")、解析符号连接(对于 unix 平台),以及将驱动器号转换为标准大小写形式(对于 microsoft windows 平台)。
 
每个表示现存文件或目录的路径名都有一个惟一的规范形式
每个表示不存在文件或目录的路径名也有一个惟一的规范形式。
不存在文件或目录路径名的规范形式可能不同于创建文件或目录之后同一路径名的规范形式。
同样,现存文件或目录路径名的规范形式可能不同于删除文件或目录之后同一路径名的规范形式。
 
public string getcanonicalpath()
                        throws ioexception
规范路径名字符串,它与此抽象路径名表示相同的文件或目录
 
public file getcanonicalfile()
                      throws ioexception
等同于 new file(this.getcanonicalpath()) 
 
 
public long getfreespace()
public long gettotalspace()
public long getusablespace()
返回此抽象路径名指定的分区中空间相关的数据信息,一定注意是抽象路径名指定的分区
未分配 /全部/已使用   空间情况
单位是字节数

file相关的操作

创建 重命名 删除等
mkdir()
 
创建此抽象路径名指定的目录,当且仅当已创建目录时,返回 true;否则返回 false
mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
注意,此操作失败时也可能已经成功地创建了一部分必需的父目录。 
 
mkdir/mkdirs  用于创建目录
mkdir只会创建最后一个名称为名称的目录,  如果一个路径的parent不存在,并不会创建成功
mkdirs 则会创建所有
 
public boolean renameto(file dest) 重新命名此抽象路径名表示的文件。
参数为file
此方法行为的许多方面都是与平台有关的:重命名操作无法将一个文件从一个文件系统移动到另一个文件系统,
该操作不是不可分的,如果已经存在具有目标抽象路径名的文件,那么该操作可能无法获得成功。
应该始终检查返回值,以确保重命名操作成功。
他的参数为file 也是一个抽象路径名 所以说不仅仅就是改一下文件的最后一个名称
他可以把文件进行移动
 
public boolean delete() 删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。
当且仅当成功删除文件或目录时,返回 true;否则返回 false 
public void deleteonexit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。 
文件(或目录)将以与注册相反的顺序删除。
调用此方法删除已注册为删除的文件或目录无效。
根据 java 语言规范中的定义,只有在虚拟机正常终止时,才会尝试执行删除操作。
一旦请求了删除操作,就无法取消该请求。所以应小心使用此方法。
 
file1 是文件  file2是目录,但是目录下还有文件
所以file1删除成功  file2删除失败
 
 
 
public static file createtempfile(string prefix,
                                  string suffix,
                                  file directory)
                          throws ioexception
在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
如果 directory 参数为 null,则使用与系统有关的默认临时文件目录
默认临时文件目录由系统属性 java.io.tmpdir 指定
public static file createtempfile(string prefix,
                                  string suffix)
                           throws ioexception
在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
调用此方法等同于调用 createtempfile(prefix, suffix, null)
public boolean createnewfile()
                      throws ioexception
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
检查文件是否存在,若不存在则创建该文件
如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false

file相关的列表查询

public string[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
如果此抽象路径名不表示一个目录,那么此方法将返回 null。
否则返回一个字符串数组,每个数组元素对应目录中的每个文件或目录。
表示目录本身及其父目录的名称不包括在结果中。每个字符串是一个文件名,而不是一条完整路径。
public string[] list(filenamefilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
除了返回数组中的字符串必须满足过滤器外,此方法的行为与 list() 方法相同。
如果给定 filter 为 null,则接受所有名称。
public file[] listfiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
如果此抽象路径名不表示一个目录,那么此方法将返回 null。
否则返回一个 file 对象数组,每个数组元素对应目录中的每个文件或目录。
表示目录本身及其父目录的名称不包括在结果中。
不保证所得数组中的相同字符串将以特定顺序出现,特别是不保证它们按字母顺序出现。
public file[] listfiles(filenamefilter filter) 除了返回数组中的路径名必须满足过滤器外,此方法的行为与 listfiles() 方法相同
如果给定 filter 为 null,则接受所有路径名
public file[] listfiles(filefilter filter) 除了返回数组中的路径名必须满足过滤器外,此方法的行为与 listfiles() 方法相同。
如果给定 filter 为 null,则接受所有路径名。
public static file[] listroots()
列出可用的文件系统根。
特定 java 平台可以支持零个或更多个分层组织的文件系统。
每个文件系统有一个 root 目录,可以从这里到达文件系统中的所有其他文件。
例如,windows 平台为每个活动驱动器提供了一个根目录;
unix 平台只有一个根目录,即 "/"。
可用文件系统根的设置受各种系统级操作的影响,比如可移动介质的插入和弹出,以及断开或卸载那些物理磁盘或虚拟磁盘。
 
此方法返回一个 file 对象数组,这些对象表示可用文件系统根的根目录。
可以保证本地机器上物理存在的任何文件的规范路径名都以此方法返回的根之一开始。
 
 
 
list返回的是名称列表 ,必须是一个目录
listfile返回的是file列表 必须是一个目录
ps:直接打印f 调用的是tostring  形式,返回的是path
 
过滤器形式的与无参数版本的行为是相同的,只不过是还要符合过滤器的要求
 
对于filenamefilter  和 filefilter,他们是函数式接口
可以直接使用lambda表达式传入参数
 
 
对函数式接口不熟悉的可以翻阅之前关于java8的文章,当然你也可以匿名内部类或者实现它,显然lambda表达式是最方便的
下面是调用过程
从上面的调用可以看得出来,
filenamefilter  当前抽象路径名以及所有的名字会传入到方法中
filefilter则仅仅只有每个抽象路径名
 
测试  filenamefilter时  下面没使用到第一个参数,这个你根据实际情况来
 
listroots

file相关权限设置

public boolean canexecute() 测试应用程序是否可以执行此抽象路径名表示的文件。
public boolean canread() 测试应用程序是否可以读取此抽象路径名表示的文件。
public boolean canread() 测试应用程序是否可以修改此抽象路径名表示的文件。
setexecutable(boolean)
setexecutable(boolean, boolean)
设置此抽象路径名的所有者或所有用户的执行权限。
executable - 如果为 true,则设置允许执行操作的访问权限;如果为 false,则不允许执行操作。
owneronly - 如果为 true,则执行权限只适用于所有者的执行权限;否则适用于所有用户。
 
如果底层文件系统不能区分所有者执行权限与其他执行权限,那么无论该参数为何值,执行权限将适用于所有用户。
 
单参数版本是双参数版本的快捷默认设置形式
file.setexcutable(arg) 形式的调用与以下调用的行为完全相同:file.setexecutable(arg, true) 
也就是单参数默认是设置当前用户
setreadable(boolean)
setreadable(boolean, boolean)
设置此抽象路径名的所有者或所有用户的读权限。

其余的用法形式同setexecutable
setwritable(boolean)
setwritable(boolean, boolean)
设置此抽象路径名的所有者或所有用户的写权限。
 
其余的用法形式同setexecutable
setexecutable/setreadable/setwritable 用于设置 执行   读   写 权限
双参数版本  第一个参数表示是否允许,第二个参数表示是否是用于所有的用户
一个参数版本是两个参数版本的当前用户的简化快捷形式
public boolean setreadonly()
标记此抽象路径名指定的文件或目录,从而只能对其进行读操作。
调用此方法后,可以保证在被删除或被标记为允许写访问之前,文件或目录不会发生更改。
是否可以删除某个只读文件或目录则取决于底层系统。

public boolean setlastmodified(long time) 设置此抽象路径名指定的文件或目录的最后一次修改时间。

其他

public path topath() 返回一个java.nio.file.path   从这个抽象路径构造的path对象
1.7新增的
public string tostring() 返回此抽象路径名的路径名字符串。该字符串就是 getpath() 方法返回的字符串。
    public string tostring() {
        return getpath();
    }
 
public uri touri()
构造一个表示此抽象路径名的 file: uri。
该 uri 的具体形式与系统有关。如果可以确定此抽象路径名表示的文件是一个目录,那么所得 uri 将以斜杠结束。
 
对于某个给定抽象路径名 f,可保证:
 
new file( f.touri()).equals( f.getabsolutefile())
 
 
public int compareto(file pathname) 按字母顺序比较两个抽象路径名。此方法定义的顺序取决于底层系统。
在 unix 系统上,比较路径名时,字母大小写通常很重要,而在 microsoft windows 系统上,这通常不重要。
依赖
public boolean equals(object obj) 测试此抽象路径名与给定对象是否相等。
当且仅当该参数不是 null,而是一个与此抽象路径名表示相同的文件或目录的抽象路径名时,返回 true。
两个抽象路径名是否相等取决于底层系统。
在 unix 系统上,比较路径名时,字母大小写通常很重要,而在 microsoft windows 系统上,这通常不重要。 
public int hashcode() 计算此抽象路径名的哈希码。
因为抽象路径名的相等性与系统有关,所以对其哈希码的计算也与系统有关。
在 unix 系统上,抽象路径名的哈希码等于其路径名字符串和十进制值 1234321 的哈希码的异或。
在 microsoft windows 系统上,哈希码等于其转换为小写的路径名字符串和十进制值 1234321 的哈希码的异或。
在将路径名字符串转换为小写时不考虑语言环境。 
 

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
他们到底都是在说什么事情呢
 
先说下标准化,看一个例子
我们给出了一个很奇怪的路径字符串
"d://////\\\\\\/testfile\\\\///////\\wdwqdwqwd.java"


file file = new file("d://////\\\\\\/testfile\\\\///////\\wdwqdwqwd.java");

if (file.exists()){

system.out.println(file.getname());

}

 

 
虽然看起来很奇怪,但是不影响程序运行
我们此时可以用比较通俗的话来描述这个情况
我们给出来了一个乱七八糟的路径,最终路径按照当前文件系统的规则,进行了解析,
去除了不必要的分隔符 或者可能把错误的分隔符进行替换等按照一定的规则
整理出来一个合理的路径,这就是标准化
 
debug 看下file的构造方法  就知道了
最终他帮我们正确的解析了路径,这就是标准化
 
可以看得出来,标准化,借助的仍旧是fs  也就是filesystem
 
在winntfilesystem 中的normalize方法就是标准化路径的一个对外接口
他还有两个相关的private方法,用于处理细节
方法的具体过程,到底是怎么处理的,有兴趣的同学可以继续深挖以下
仔细看下注释也可理解一二
一个标准的win32路径名,不能包括重复的名称分隔符(斜杠) unc除外 ,也不能以名称分隔符(斜杠)结束
可能是一个空的string
规范化win32路径名具有便捷的特点:前缀的长度几乎唯一地标识了路径的类型
无论它是绝对的还是相对的
0,1,2,3是分类说明
 
如同上面标准化描述的一样,前缀的长度对于标准化很有用,这个方法经常被使用
 

相关文章:

验证码:
移动技术网