目录
认识文件
我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往 往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念, 就类似办公桌上的一份份真实的文件一般。
文件除了有数据内容之外,还有一部分信息,例如文件名、文件类型、文件大小等并不作为文件的数据 而存在,我们把这部分信息可以视为文件的元信息
硬件: 处理器(CPU)、存储器(内存)、输入设备(Input Device)、输出设备(Output Device)
注释:CPU只能和内存做直接的数据交换
Input Device: 现实中的物理信号(光信号、电信号、波信号) -> 数字个数,存储在内存中
Output Device: 数字 -> 物理信号
IO设备:显示器(O)、触屏显示器(IO)、鼠标(I)、键盘(I)、摄像头(I)、麦克风(I)、扬声器(O)
最常见的I/O设备:硬盘(IO)、网卡(IO)
注释:输入设备和输出设备统称为 I/O
计算机的存储常识
各个存储访问速度的一个直观感受
总结:
硬盘的实现 Hard Disk Drive HDD
一般来说的硬盘,指的都是磁盘,也就是机械硬盘。
1.磁盘(利用磁性实现的一种存储方式) 硬盘(机械硬盘)
2.固态硬盘(Solid State Disk SSD)
3.闪存(Flash Memory)
硬盘里面的数据可以分为两大类
硬盘数据的读写->文件的读写问题
OS+文件系统(FileSystem) 统一管理文件
作为软件开发工程师,大部分场景只需要关注这个逻辑结构即可不需要管理物理结构
小知识:
关于文件的路径
比如:
这里的“我们”可以类比是当前自身所处的位置,位置一变,就失效了。
什么叫做“我们”所在的位置:
每个进程都有一个当前工作目录(current working directorycwd) ,一般一个进程的启动目录,就是当前工作目录
比如:
如何描述路径
windows 下,先以绝对路径为例
比如:D:\qq\Bin\qq.exe
注释: \ 被称为路径分割符
C:、D:、E:代表的就是根
所以,这个以根开头的路径一定是个绝对路径
文件名+文件名+文件名...组成
1. 从根 D开始
2. 找到它(D:)的子孩子 qq
3. 找到它 (qq)的子孩子 Bin
4. 找到它(Bin)的子孩子 qq.exe
相对路径
如果“我们”此时身处
那么我们描述的就是:Bin\qq.exe
不是由根开始,所以是相对路径
但是两个路径描述的是同一个结点
举例:现实生活中的问路
如果别人问你最近厕所在哪?你可能会说前面左拐 50米就到了,而你说这个位置的前提下是以你当前所处的位置为基础的,比如:xx省xx市xx区xx街道为前提,如果你此时身处北京,上海等某个地方,你能说前面左拐50就是厕所吗? 所以这就是相对路径,是以当前位置为基础的。
如果别人问你鸟巢怎么走?你基本就会说,北京市,xxxx体育馆 不管你在什么地方,都跟根据这个地址找到目的地,就是这绝对路径
在代码的字符串中如何表示这个路径
比如上面的qq路径:D:\qq\Bin\qq.exe
如果直接这么写:String str = "D:\qq\Bin\qq.exe"; 这样是错的
原因:因为字符串中反斜杠(\),表示转义的意思比如 \n、\t ...
正确写法:String str = "D:\\qq\\Bin\\qq.exe";
使用 \\ 转义后表示 \
注释:正斜杠只有写一个,反斜杠因为需要转义所以需要写两个
所以上面的路径可以这么写:D:/qq/Bin/qq.exe
路径表示中的两个特殊的符合
注释: C盘,D盘是根目录,没有父节点,所以再怎么../ 最多也只能回到根节点上
比如:
D:/qq/Bin/qq.exe 和 D:/qq/./Bin/qq.exe 多了一个./ 但两者还是一样的,有没有都一样 . 表示不动
D:/qq/Bin/ == D:/qq/Bin/../Bin/ (回到上级目录再次回来)
注释:. 和 .. 都是要配合分割符 / 或 \\ 使用
关于文件的路径小总结
问题:关于文件叶子节点
树的结点分为:叶子结点 or 非叶子结点
那么 普通文件属于: 叶子结点 or 非叶子结点
目录文件属于: 叶子结点 or 非叶子结点
答:普通文件肯定属于 叶子节点,找个这个文件就是找到头了阿,目的地达到了,不可能再继续访问下去了。
目录文件属于 叶子节点(空目录) 或者 非叶子节点, 只有这个目录里面还有东西存在就属于非叶子节点
注释:文件系统中的任何操作,都是以结点为单位进行操作的,文件的移动,复制等等。
树的操作,需要转换成结点的操作:以目录的复制为例,遍历(深度or广度)整棵树,然后对其中的每个结点进行复制。
回顾以前的知识:
通过Java 代码操作文件(File)
接下来,我们只关注元数据本身,暂时不管内容数据。
对文件系统树的操作
判断是否存在、判断是否是目录、创建、删除、重命名..
File 对象描述一个文件(结点,结点对应的文件是否存在并不一定)
File (Java Platform SE 8 ) (oracle.com) File类的介绍和方法使用规则
创建File对象的三种方法形式
package com.mabaijing.io;
import java.io.File;
public class Domo1 {
public static void main(String[] args) {
//1. 绝对路径的方式创建
//1.1 直接传入一个字符串路径即可,idea会自动帮你写好分割符规范
File file1 = new File("D:\\code_Java\\rocket_class_io\\src\\hello.txt");
//1.2 传入父路径 + 子路径
File file2 = new File("D:\\code_Java\\rocket_class_io\\src", "hello.txt");
//1.3 以File 传入parent
File parent = new File("D:\\code_Java\\rocket_class_io\\src");
File file3 = new File(parent, "hello.txt");
int cmp1 = file1.compareTo(file2);
int cmp2 = file1.compareTo(file3);
System.out.println(cmp1);
System.out.println(cmp2);
}
}
0表示相等,都指向同一个地方。
File一些方法介绍
会返回三种不同的情况
注释:以前的代码不管执行多少次结果都是一样的,因为不太需要依赖外部环境,现在不一样了,第一次执行和第二次执行的结果就不一样,需要看外部环境。即使代码完全一样,根据执行的次数、顺序不同都可能得到不同的结果。
如果我们输入的文件路径有不存在的目录,就会报错
比如删除我们刚刚创建world.txt文件
如果是删空目录也是可以删除成功的,可一旦目录里面有内容,就必须先把目录里面的内容删了才能删目录。
删除一个目录里面的全面内容,深度优先遍历
import java.io.File;
public class Domo2 {
public static void main(String[] args)throws Exception {
File file = new File("D:\\code_Java\\rocket_class_io\\src\\world.txt");
// boolean r = file.delete();
// System.out.println(r);
traversal(file);
}
private static void traversal(File dir) throws Exception {
File[] files = dir.listFiles(); // 查看这个目录下的所有孩子(不是子孙)
for (File file : files) {
if (file.isDirectory()) { // 如果这个孩子也是目录,继续深度优先进行遍历
System.out.println(file.getCanonicalPath() + "\\");//打印路径
traversal(file);//用递归删除孩子里面的内容
// 当深度优先的遍历完成时,则可以认为该目录一定是空目录了
file.delete();
} else {
System.out.println(file.getCanonicalPath()); //打印路径 // 得到这个文件的一个标准(去除一切无意义的 . 和 ..)
file.delete();
}
}
}
}