(一)什么是文件
对于硬盘这种频繁进行IO的硬件,我们在保存数据时往往保存一个整体,而是将这个整体拆成多个模块,这种模块就类似于文件
文件的属性,文件除了有我们保存的数据外,还有很多属于自己的属性,,例如⽂件名、⽂件类型、⽂件⼤⼩等并不作为⽂件的数 据⽽存在,我们把这部分信息可以视为⽂件的元信息
(二)文件如何管理
我们的计算机上有很多文件,那如果我们像是顺序表一样管理,那么管理起来就会很复杂,所以我们计算机用层级结构(树形结构)来进行管理,这也就诞生了我们文件夹和目录的概念。
通过层级结构,我们可以更方便的找到想要的文件,更方便用户的使用
文件路径
我们上面说是用层级结构来对文件进行管理
我们都学过树的遍历,而由根节点找到目标结点的路径就跟我们这里的文件路径一样,而由跟结点 出发到达目标结点的路径,在这里被叫做绝对路径
除了由跟结点开始,我们也可以从任意一个结点开始,此时到达目标节点的路径,被叫做相对路径
一些其他的知识
1)文件分类:即使是普通⽂件,根据其保存数据的不同,也经常被分为不同的类型,我们⼀般简单的划分为⽂本⽂件和⼆进制⽂件,分别指代保存被字符集编码的⽂本和按照标准格式保存的⾮被字符集编码过的⽂件
2)文件的权限:文件由于被操作系统统一管理,所以我们对不同用户操作文件,有不同的权限,一般地可以认为有可读、可写、可执行权限。
(三)如何操作文件
Java中通过java.io.File 类来对⼀个⽂件(包括⽬录)进⾏抽象的描述。注意,有File对象, 并不代表真实存在该⽂件。
File类
我们先来看一下File类中有什么属性和构造方法
我们来看他的构造方法:
第一个是根据父目录和孩子文件路径,创建出一个File实例
第二个是根据文件路径创建一个新的File实例,路径可以是相对路径,也可以是绝对路径
第三个是根据父目录和孩子文件路径,创建一个新的File实例,父目录用路径表示
第四个是 URI 转换为抽象路径名来创建新的 File 实例。
至于方法jdk api有太多了,我找了一个比较少但是很关键的表
那光看肯定不行,所以通过代码来用一下这些方法
1.文件的路径
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("..\\hello.txt");
System.out.println(file.getParent());
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsoluteFile());
System.out.println(file.getCanonicalPath());
}
2.文件的创建
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("..\\hello.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.isDirectory());
}
这里的creatNewFile方法需要我们的文件不存在才能创建成功,如果存在会返回false
3.文件的删除
(1)通过delete删除
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("..\\hello.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.createNewFile());
System.out.println(file.delete());
System.out.println(file.exists());
System.out.println(file.isDirectory());
}
这里delete在删除成功后会返回true,如果失败会返回false
(2)通过deleteOnexit来进行删除
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("..\\hello.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.createNewFile());
file.deleteOnExit();
System.out.println(file.exists());
System.out.println(file.isDirectory());
}
deleteOnExit返回值为空,在进程没有结束时不会删除我们的文件,而当进程关闭后,才会进行删除操作
4.目录的创建
(1)通过mkdir
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File dir=new File("..\\hello.txt");
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdir());
System.out.println(dir.isFile());
System.out.println(dir.isDirectory());
}
与文件的创建类似,我们就不多说了
(2)通过mkdirs
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File dir=new File("hello\\hello2.txt");
System.out.println(dir.isDirectory());
System.out.println(dir.mkdir());
System.out.println(dir.isDirectory());
System.out.println(dir.mkdirs());
System.out.println(dir.isDirectory());
}
mkdir()的时候,如果中间⽬录不存在,则⽆法创建成功;mkdirs()可以解决这个问题
目录的删除和文件一样都是通过delete和deleteOnExit来进行删除
5.文件的重命名
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("..\\hello1.txt");
File file1=new File("..\\hello2.txt");
file.delete();
file1.delete();
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.renameTo(file1));
System.out.println(file.exists());
System.out.println(file1.exists());
}
注意这里我们要求file本身是存在的,file1是不存在的,这样才可以重命名,然后我们发现file被删除,file1创建出来(其实我个人认为这里是创建了一个file1,将file中的数据拷贝到file1中)
(四)文件的读写(数据流)
我们先来看一下文件读写所需要用到的方法
使用InputStream
我们需要用到iputstream中的一些方法
我们注意Inputstream是一个抽象类,如果想要具体实现,因为我们是文件IO所以需要用到FileInputstream
那我们正好来看一下FileInptstream的构造方法
那么知道了如何构造,也知道了如何去使用,那我们就来尝试下向文件中读数据
注意我们从文件中读数据,需要文件已经存在
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.exists();
InputStream inputStream=new FileInputStream("../hello");
while(true){
int b=inputStream.read();
if (b==-1){
//文件读完了
break;
}
}
}
这时通过用无参read的方式来读,我们可以在read中放入一个byte数组来存
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.delete();
file.exists();
InputStream inputStream=new FileInputStream("../hello");
byte[] buf=new byte[1024];
while(true){
int b=inputStream.read(buf);
if (b==-1){
//文件读完了
break;
}
}
}
这里读的都是英文也就是一个一个字符,那如果我们想读取汉字,该如何读呢
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.delete();
file.exists();
InputStream inputStream=new FileInputStream("../hello");
byte[] buf=new byte[1024];
int b=0;
while(true){
b=inputStream.read(buf);
if (b==-1){
//文件读完了
break;
}
for (int i = 0; i < b; i+=3) {
String s=new String(buf,i,3,"UTF-8");
System.out.println(s);
}
}
}
我们可以利用汉字的UTF-8编码是三个字节的特点,来从文件读取,但是不通用,只适用于全汉字且长度受限。
使用Scanner
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.delete();
file.exists();
InputStream inputStream=new FileInputStream("../hello");
Scanner scanner=new Scanner(file,"utf-8");
while(scanner.hasNext()){
String s=scanner.next();
System.out.print(s);
}
}
说完了读,那我们再来说如何向文件中写数据
使用OutputStream
与InputStream类似,他也是一个抽象类,我们向文件中写数据需要用到FileOutputStream
但注意我们这里的flush方法,我们io的时候,可能一次传输的数据不多但是多次,所以为了减少io的次数,我们会有一个缓冲区来存数据,等缓冲区满了或者被冲刷,我们才真正将数据写入,所以在之后的代码也可能会有这种问题,那么就需要我们调用flush方法来手动冲刷缓冲区,确保我们的数据是最新的。
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.delete();
file.exists();
OutputStream outputStream=new FileOutputStream("../hello");
outputStream.write(1);
outputStream.write(2);
outputStream.write(3);
outputStream.flush();
}
我们也可以类似InputStream通过字符数组的方式向文件写数据
public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
File file=new File("../hello");
file.delete();
file.exists();
OutputStream outputStream=new FileOutputStream("../hello");
String s="点个赞再走吧";
byte[] arr=s.getBytes("UTF-8");
outputStream.write(arr);
outputStream.flush();
}