一、前言
文件 -> 硬盘(磁盘) 硬盘 != 磁盘
计算机中的存储设备:
速度 内存 价格 关机后文件
1. CPU 最快 最小 最贵 丢失
2. 内存 其次 其次 其次 丢失
3. 硬盘 最慢 最大 最便宜 不丢失
此处谈到的文件是存储再硬盘上的文件,很多的特性都和硬盘特性相关
对于计算机来说, " 文件 " 是一个很广义的概念 -> 硬盘上的普通文件,硬盘上的目录
很多的硬件设备,也是被操作系统抽象成了文件 键盘 显示器 网卡...
二、路径
操作系统,使用"路径"这样一个概念来描述具体文件的位置.
ps: 文件系统是按照 "树形结构" 来组织文件的. 这里的树是N叉树.
形如:F:\java\test.txt
像这样从根节点F( windows是盘符 ),一级一级往下走,走到目的文件,把中间经过的所有的目录的名字都串起来,使用 " / "或者 " \ " 分割,这就构成了路径.
路径有两种不同的风格
1. 绝对路径. 指的就是从数根节点出发( windows是盘符 ),一层一层最终到达目的文件.
2. 相对路径. 先制定一个 "当前目录" / "工作目录" / "基准目录" ,从当前目录出发,找到目标文件.
如果此时test.txt的目录是: C:\Users\1
此时相对路径就是./test.txt -> 此处的 " . " 就表示当前目录
如果当前目录是 : C:\Users
那么此时相对路径就是./1/test.txt
如果当前目录是 : C:\Users\1\AppData
此时相对路径就是 : ../test.txt -> 此处的 " .. " 就表示上层目录
开发时,我们使用的更多的是相对路径.
三、文件重要分类
文件分为 : 文本文件和二进制文件.
如何区分这两种文件呢?
用一个记事本打开文件,如果看到的是文本,那就是文本文件,如果看到的是乱码,那就是二进制文件.
四、Java对于文件操作的api
1. 针对文件系统的操作,包括不限于 : 创建文件、删除文件、重命名文件、列出目录内容...
2. 针对文件内容的操作 -> 读文件、写文件
Java中针对文件系统的操作,使用File类来进行,这个类所在的包叫做 java.io
-> input ( 输入 ) output ( 输出 )
数据从硬盘到CPU叫输入,从CPU到硬盘叫输出
五、File类
5.1 属性
修饰符及类型 属性 说明
static String pathSeparator 依赖于系统的路径分隔符,String类型的表示
static char pathSeparator 依赖于系统的路径分隔符,char类型的表示
5.2 构造方法
签名 说明
File( File parent , String child) 根据父目录+孩子文件路径,创建一个File实例
File( String pathname) 根据文件路径创建一个新的File实例,路径可以是绝对路径
或者相对路径
File( String parent , String child ) 根据父目录+孩子文件路径,创建一个新的File实例,父目录用
路径表示
5.3 方法
修饰符及返回值类型 ⽅法签名 说明
String getParent() 返回File对象的⽗⽬录⽂件路径
String getName() 返回FIle对象的纯⽂件名称
String getPath() 返回File对象的⽂件路径
String getAbsolutePath() 返回File对象的绝对路径
String getCanonicalPath() 返回File对象的修饰过的绝对路径 boolean exists() 判断File对象描述的⽂件是否真实 存在
boolean isDirectory() 判断File对象代表的⽂件是否是⼀个⽬录 boolean isFile() 判断File对象代表的⽂件是否是⼀ 个普通⽂件 boolean createNewFile() 根据File对象,⾃动创建⼀个空⽂ 件。成功创建
后返回true
boolean delete() 根据File对象,删除该⽂件。成功 删除后返回true
void deleteOnExit() 根据File对象,标注⽂件将被删 除,删除动作会到
JVM运⾏结束时 才会进⾏
String[] list() 返回File对象代表的⽬录下的所有 ⽂件名
File[] listFiles() 返回File对象代表的⽬录下的所有 ⽂件,以
File对象表⽰
boolean mkdir() 创建File对象代表的⽬录 boolean mkdirs() 创建File对象代表的⽬录,如果必 要,会
创建中间⽬录 boolean renameTo(Filedest) 进⾏⽂件改名,也可以视为我们平 时
的剪切、粘贴操作
boolean canRead() 判断⽤⼾是否对⽂件有可读权限 boolean canWrite() 判断⽤⼾是否对⽂件有可写权限
public static void main(String[] args) throws IOException {
File f = new File("C:/Users/1/test.txt");
System.out.println(f.getParent());
System.out.println(f.getName());
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
}
public static void main(String[] args) throws IOException {
File f = new File("./test.txt");
System.out.println(f.getParent());
System.out.println(f.getName());
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
}
通过调用这些方法,我们可以发现,创建实例File时,传如相对路径和绝对路径所得到的结果是不同的.
一个是我们传入的路径,一个是运行程序的电脑中的路径
六、流
文件内容的操作——流
流是操作系统提供的概念.
Java标准库对于流进行了一系列的封装了.
提供了一组类来负责进行这些工作.
针对这么多类,可以大体分成两个大类别
6.1 字节流
以字节为单位进行读写. 一次最少读写一个字节.
代表类:
InputStream 输入(读)
OutputStream 输出
6.2 字符流
以字符为单位进行读写了.
代表类 :
Reader 输入(读)
Writer 输出
ps:这四个类都是抽象类,只能构造出子类来使用.
I你putStream实例创建后,就可以调用read();方法来读取文件的内容.
read有三个版本:
无参数版本,即每次调用读取一个字节,返回值就表示读取到的这个字节的值.
一个参数的版本,传入的字节数组参数,是一个 " 输出型参数 ",byte[]就是引用类型,方法内部针对数组内容进行修改,方法执行结束后,方法外部,也能生效.
read方法的返回值看起来是int,实际上是byte
此外,还有一个特殊情况,如果读取到文件的末尾,继续进行read就会返回-1
使用read的时候,往往就是定义一个内容为空的数组,(不是null)把控的数组交给read,read内部对数组内容进行填充.
rea的第二个和第三个版本,返回的int代表实际读取的字节个数.
默认情况下,read会把数组填满,但是文件的实际剩余长度可能不足以填满了.
返回值就可以告诉我们实际填充了多少字节.
在用InputStream打开文件后,要使用close将文件关闭.
但是为了防止出现问题导致文件没有被关闭:
try (InputStream inputStream = new FileInputStream("./aaa/test.txt")){
}catch(){
}
我们可以用这种方式打开文件,一旦出了try,此时try就会自动调用inputstream的close