目录
1. 什么是文件
1.1. 文件的概念
针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,这就叫做文件。
1.2. 树形结构和目录
文件管理采用的是树形结构,是N叉树,至于目录,其实就是文件夹。
1.3. 文件路径
路径分为绝对路径和相对路径。
绝对路径:从树的根部开始查找。
相对路径:从树的某一个节点为基准进行查找。
1.4. 文件类型
主要了解文本文件和二进制文件。
文本文件里存储的数据,就是遵守由 ASCII 或者其他字符集编码所得到的文件。本质上存储的是 字符!
二进制文件存储的数据则没有任何字符集的限制。不受限制,存啥都行!
简单粗暴判定:用记事本打开文件,能看懂的是文本文件,一堆乱码看不懂的是二进制文件。
1.5. 文件流
文件在程序中是以流的形式操作的。
流:数据在数据源(文件)和程序(内存)之间经历的路径;
输入流:数据从数据源(文件)到程序(内存)的路径;
输出流:数据从程序(内存)到数据源(文件)的路径。
2. 文件操作
Java标准库提供了File这个类,在内存中创建出File对象,这个对象就是硬盘上的文件的“抽象”表示,类似于一个遥控器,我们可以通过在内存中对这个对象的操作,影响到硬盘中的文件。
File file = new File("./cat.jpg"); // 相对路径构造对象
File file = new File("d:/cat.jpg"); // 绝对路径构造
File file = new File(File parent, String child) // 根据父目录文件+子路径构建
File file = new File(String parent, String child) // 根据父目录+子路径构建
file.createNewFile(); //如果输入的路径下文件不存在,手动调用这个方法,会创建一个文件
File提供的方法
方法名 | 说明 |
---|---|
getParent() | 获取父级目录文件路径 |
getAbsolutePath() | 获取绝对路径 |
getName() | 获取文件名称 |
delete() | 删除文件 |
exists() | 该文件是否存在 |
isFile() | 是否为文件 |
isDirectory() | 是否为目录 |
mkdir() | 创建目录 |
mkdirs() | 创建多级目录 |
renameTO() | 文件重命名(也视为剪切粘贴操作) |
list | 返回一个字符串数组, 内容是该路径下的文件和目录 |
listFiles | 返回一个File类型的数组, 内容是该路径下表示的目录中的文件。 |
代码示例
获取文件路径
File file = new File("./cat.jpg");
//返回 File 对象的父目录文件路径获取文件名称
System.out.println(file.getParent());
//返回 FIle 对象的纯文件名称
System.out.println(file.getName());
//返回 File 对象的文件相对路径
System.out.println(file.getPath());
//返回 File 对象的绝对路径
System.out.println(file.getAbsolutePath());
//返回 File 对象的修饰过的绝对路径
System.out.println(file.getCanonicalPath());
运行结果
文件的判断方法
File file = new File("./hello_World.txt");
//判定文件是否存在
System.out.println(file.exists());
//判断 File 对象代表的文件是否是一个目录
System.out.println(file.isDirectory());
//判断 File 对象代表的文件是否是一个普通文件
System.out.println(file.isFile());
//创建文件
file.createNewFile();
System.out.println("创建文件后: ");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println("删除文件");
file.delete();
System.out.println(file.exists());
运行结果
路径下的文件
File file = new File("test-dir");
String[] list = file.list();
File[] files = file.listFiles();
System.out.println(Arrays.toString(list));
System.out.println(Arrays.toString(files));
运行结果
目录的创建及重命名
File file1 = new File("test");
//创建一级目录
file1.mkdir();
File file = new File("test-dir/aaa/bbb/ccc");
//创建多级目录
file.mkdirs();
File oldFile = new File("./test-dir");
File newFile = new File("./test111");
//重命名
oldFile.renameTo(newFile);
运行结果
三,文件内容操作
针对文本文件,提供一组类,统称为 字符流。(典型代表:Reader,Writer)
针对二进制文件,提供一组类,统称为 字节流。(典型代表:InputStream,OutPutStream)
字节流读文件
try (InputStream inputStream = new FileInputStream("d:/test.txt")){
//读操作
//无参数的 read, 相当于一次读一个字节, 返回值类型是 int
while (true) {
int b = inputStream.read();
if(b==-1) {
//读到末尾了,结束循环即可
break;
}
System.out.println(b);
}
}
read方法的参数
无参版本: 一次读一个字节, 返回值是 int 。最后返回 -1 表示文件读完。
按照字节数组读取: 一次读多个字符, 提高效率,同样返回 -1 表示读完。
字节流写文件
public class Study5_2_二进制文件的写 {
public static void main(String[] args) {
try (OutputStream outputStream = new FileOutputStream("d:/test.txt")){
//写入内容
outputStream.write(97);
outputStream.write(98);
outputStream.write(99);
outputStream.write(100);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
字符流读文件
try(Reader reader = new FileReader("d:/text.txt")){
while (true) {
int c = reader.read();
if(c==-1) {
break;
}
char ch = (char)c;
System.out.print(ch);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
字符流读文件
try(Writer writer = new FileWriter("d:/text.txt")) {
writer.write('再');
writer.write('见');
} catch (IOException e) {
e.printStackTrace();
}
注意
上述操作没有手动 .close()关闭文件是因为这里使用的 try 代码块,代码块中若带有资源,出代码块后会自动释放资源。
每打开一个文件,都会在文件描述符表中申请一个位置,表的长度是有限的,如果不关闭,当表满了的时候,还继续打开文件,就会发现,文件打不开,这就是文件资源泄露。