@[TOC](文件操作和IO)
文件操作和IO
- 认识⽂件
- 树型结构组织 和 ⽬录
- 文件路径(Path)
- 其他知识
- Java 中操作⽂件
- File 概述
- 代码⽰例
认识⽂件
我们先来认识狭义上的⽂件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进⾏数据保存时,往往不是保存成⼀个整体,⽽是独⽴成⼀个个的单位进⾏保存,这个独⽴的单位就被抽象成⽂件的概念,就类似办公桌上的⼀份份真实的⽂件⼀般。
⽂件除了有数据内容之外,还有⼀部分信息,例如⽂件名、⽂件类型、⽂件⼤⼩等并不作为⽂件的数据⽽存在,我们把这部分信息可以视为⽂件的元信息。
虽然硬盘有上述结构,程序员来说,咱们写代码不太涉及到这些硬盘的结构细节的操作系统都封装好了.
操作系统有一个专门的模块,文件系统~~ 把硬件细节封装好,提供统-的 api 来供咱们调用.
树型结构组织 和 ⽬录
同时,随着⽂件越来越多,对⽂件的系统管理也被提上了⽇程,如何进⾏⽂件的组织呢,⼀种合乎⾃然的想法出现了,就是按照层级结构进⾏组织⸺也就是我们数据结构中学习过的树形结构。这样,⼀种专⻔⽤来存放管理信息的特殊⽂件诞⽣了,也就是我们平时所谓⽂件夹(folder)或者⽬录(directory)的概念。
此处文件系统是按照"树形结构"来组织文件的,这里的树,不是"二叉树",而是 N 叉树每一个普通文件(非目录) 就是叶子节点. 一个目录文件来说,里面又可以有很多的子节点~
文件路径(Path)
如何在⽂件系统中如何定位我们的⼀个唯⼀的⽂件就成为当前要解决的问题。从树根节点出发(windows 上是从盘符出发),一级一级的往下走,走到目标的文件,把中间经过的所有的目录的名字都串起来,使用/或者\分割. 此时就构成了"路径"
树中的每个结点都可以被⼀条从根开始,⼀直到达的结点的路径所描述,⽽这种描述⽅式就被称为⽂件的绝对路径(absolute path)。
(绝对路径,指的就是从树根节点出发 (Windows 是盘符),一层一层最终到达目标文件)
我们还可以从任意结点出发,进⾏路径的描述,⽽这种描述⽅式就被称为相对路径(relative path),相对于当前所在结点的⼀条路径。(相对路径,先指定一个"当前目录”/“工作目录”/"基准目录!从当前目录出发,找到目标文件)
实际开发中,更多的是使用相对路径~~
路径分隔 使用 / 还是 \ 呢
(不重要的小知识)Everything为啥那么快?
其他知识
即使是普通⽂件,根据其保存数据的不同,也经常被分为不同的类型,我们⼀般简单的划分为⽂本⽂件和⼆进制⽂件,分别指代保存被字符集编码的⽂本和按照标准格式保存的⾮被字符集编码过的⽂件。
此处说的“文本文件"是按照"文本"/字符串,方式来理解文件内容 (文本文件里面的二进制内容,都是表示的字符串)进一步可以认为,文件中存储的数据都是在指定码表上有据可査,是合法的字符(字符编码:普通英文字母,使用 ascii;汉字,使用 gbk/utf8,无论是哪种方式, 都会有一个"码表"”)
而"二进制文件"则没有上述限制,这里的内容存储任何数据都可以
给你一个文件,如何判定是文本二进制呢??
文本文件和二进制文件,代码操作的方式是有差别的。
这个时候,就可以使用记事本来判定。使用记事本打开一个文件,如果你看到的是正常内容不是乱码,就说明这是文本文件,如果是乱码就是二进制文件
Windows 操作系统上,会按照⽂件名中的后缀来确定⽂件类型以及该类型⽂件的默认打开程序。但这个习俗并不是通⽤的,在 OSX、Unix、Linux 等操作系统上,就没有这样的习惯,⼀般不对⽂件类型做如此精确地分类。
⽂件由于被操作系统进⾏了管理,所以根据不同的⽤⼾,会赋予⽤⼾不同的对待该⽂件的权限,⼀般地可以认为有可读、可写、可执⾏权限。
Windows 操作系统上,还有⼀类⽂件⽐较特殊,就是平时我们看到的快捷⽅式(shortcut),这种⽂件只是对真实⽂件的⼀种引⽤⽽已。其他操作系统上也有类似的概念,例如,软链接(soft link)等。
最后,很多操作系统为了实现接⼝的统⼀性,将所有的 I/O 设备都抽象成了⽂件的概念,使⽤这⼀理念最为知名的就是 Unix、Linux 操作系统⸺万物皆⽂件。
Java 中操作⽂件
本节内容中,我们主要涉及⽂件的元信息、路径的操作,暂时不涉及关于⽂件中内容的读写操作。
Java 中通过 java.io.File 类来对⼀个⽂件(包括⽬录)进⾏抽象的描述。注意,有 File 对象,并不代表真实存在该⽂件。
数据从 硬盘 到 cpu叫做输入, 还是 cpu 到硬盘 过程叫做输入??
答案:从 硬盘 到 cpu!
屁股决定脑袋,坐在哪个位置上,你的想法就是啥样的
对于计算机来说,cpu 是最关键的部分,你就可以考虑,你屁股坐在 cpu 上来看待这个问题
File 概述
我们先来看看 File 类中的常⻅属性、构造⽅法和⽅法
属性
pathSeparator:路径之间的分隔符,根据系统自动调整的。当然实际开发中还是更建议直接使用 / .windows 也支持 /。
构造⽅法
方法
注意:
list()
代码⽰例
IOException:在你 IO 操作的过程中,出现的异常,
⽰例1
观察 get 系列的特点和差异
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File file = new File("..\\hello-world.txt"); // 并不要求该⽂件真实存在System.out.println(file.getParent());System.out.println(file.getName());System.out.println(file.getPath());System.out.println(file.getAbsolutePath());System.out.println(file.getCanonicalPath());}
}
运⾏结果
..
hello-world.txt
..\hello-world.txt
D:\代码练习\⽂件⽰例1\..\hello-world.txt
D:\代码练习\hello-world.txt
如果构造 File 对象使用绝对路径,此时上述三个 操作 确实没啥区别
但如果使用相对路径:
⽰例2
普通⽂件的创建
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File file = new File("hello-world.txt"); // 要求该⽂件不存在,才能看到相同的现象System.out.println(file.exists());System.out.println(file.isDirectory());System.out.println(file.isFile());System.out.println(file.createNewFile());System.out.println(file.exists());System.out.println(file.isDirectory());System.out.println(file.isFile());System.out.println(file.createNewFile());}
}
运⾏结果
false
false
false
true
true
false
true
false
⽰例3
普通⽂件的删除
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File file = new File("some-file.txt"); // 要求该⽂件不存在,才能看到相同的现象System.out.println(file.exists());System.out.println(file.createNewFile());System.out.println(file.exists());System.out.println(file.delete());System.out.println(file.exists());}
}
运⾏结果
false
true
true
true
false
⽰例4
观察 deleteOnExit 的现象
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File file = new File("some-file.txt"); // 要求该⽂件不存在,才能看到相同的现象System.out.println(file.exists());System.out.println(file.createNewFile());System.out.println(file.exists());file.deleteOnExit();System.out.println(file.exists());}
}
运⾏结果
false
true
true
true程序运⾏结束后,⽂件还是被删除了
deleteOnExit :退出时再删除
有的同学写这个代码的时候,可能会出现,程序退出了,但是文件还能看到。(这个情况有可能是 IDEA 的延迟,文件其实已经没了,但是 IDEA 文件列表没有及时刷新)手动选中文件列表,按下 F5 手动刷新就可以了。
退出之后再删除,这样的文件,也称为"临时文件
这个东西很有用,有些程序就带有临时文件的功能
⽰例5
观察⽬录的创建
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File dir = new File("some-dir"); // 要求该⽬录不存在,才能看到相同的现象System.out.println(dir.isDirectory());System.out.println(dir.isFile());System.out.println(dir.mkdir());System.out.println(dir.isDirectory());System.out.println(dir.isFile());}
}
运⾏结果
false
false
true
true
false
mk => make 制造
dir => directory 目录
⽰例6
观察⽬录创建2
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File dir = new File("some-parent\\some-dir"); // some-parent 和 some-dir目录不存在,才能看到相同的现象System.out.println(dir.isDirectory());System.out.println(dir.isFile());System.out.println(dir.mkdir());System.out.println(dir.isDirectory());System.out.println(dir.isFile());}
}
运⾏结果
false
false
false
false
false
mkdir() 的时候,如果中间⽬录不存在,则⽆法创建成功; mkdirs() 可以解决这个问题。
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File dir = new File("some-parent\\some-dir"); // some-parent 和 some-dir目录不存在,才能看到相同的现象System.out.println(dir.isDirectory());System.out.println(dir.isFile());System.out.println(dir.mkdirs());System.out.println(dir.isDirectory());System.out.println(dir.isFile());}
}
运⾏结果
false
false
true
true
false
mkdir和mkdirs
只是 ./aaa,使用 mkdir 即可;/aaa/bbb/ccc,使用mkdirs。
⽰例7
观察⽂件重命名
import java.io.File;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {File file = new File("some-file.txt"); // 要求 some-file.txt 得存在File dest = new File("dest.txt"); // 要求 dest.txt 不存在System.out.println(file.exists());System.out.println(dest.exists());System.out.println(file.renameTo(dest));System.out.println(file.exists());System.out.println(dest.exists());}
}
运⾏结果
true
false
true
false
true
renameTo还可以移动文件