一、文件的相关知识
1.文件的定义:
文件是具有符号名的,在逻辑上具有完整意义的一组相关信息项的有序序列。信息项是构成文件内容的基本单位。文件中的读指针用来记录文件当前文件之前的读取位置,它指向下一个将要读取的信息项,而写指针用来记录文件当前的写入位置,下一个将要写入的信息项被写到该处。文件是存储在硬盘上。
2.文件的用途:
2.1在运行程序的时候,产生的数据是存放在内存中的,当程序退出时,内存中的数据就不存在了,当我们想把数据长久保存的时候,一般是把数据存放在磁盘文件或存放到数据库中
2.2使用文件我们可以将数据直接存放到电脑的硬盘上,实现数据的持久化存储的目的
3.从功能来分,文件大致分为:
3.1程序文件:包括源程序文件(后追为.c),目标文件(windows环境后缀为.obj),可执行程序文件(windows环境后缀为.exe)。
3.2数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
4.文件的路径:
4.1绝对路径:
从盘符开始的路径,例如:C:\windows\system32\cmd.exe
特点:以根开头的路径、文件位置的全路径、在任何位置都可以引用
4.2相对路径:
若当前路径为C:\windows,只需输入:system32\cmd.exe,严格的相对路径写法应为:.\system32\cmd.exe,.表示当前路径,在通道情况下可以省略,只有在特殊的情况下不能省略;若当前路径为c:\program files,则要输入: ..\windows\system32\cmd.exe,..为上级目录;若当前路径如果为c:\program files\common files,则需要输入:..\..\windows\system32\cmd.exe,就是上级目录的上级目录
特点:不以斜线开头、当前工作目录的相对位置、在特定的位置才可以引用
5.文件系统的知识:
5.1文件系统的定义:文件系统是操作系统中负责管理持久数据的子系统,说简单点,就是负责把用户的文件存到磁盘硬件中,因为即使计算机断电了,磁盘里的数据并不会丢失,所以可以持久化的保存文件。
5.2文件系统的基本组成:文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。
5.3文件系统的作用: 从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。
二、文件IO的相关操作
Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件。
(一)、FILE类的相关知识
1.流
1.1什么是流?
流是一个抽象的概念,当Java程序需要从数据源读取数据时,会开启一个到数据源的流。数据源可以是文件,内存或者网络等。同样,当程序需要输出数据到目的地时也一样会开启一个流,数据目的地也可以是文件、内存或者网络等。流的创建是为了更方便地处理数据的输入输出。
1.2字节流:也称为原始数据,需要用户读入后进行相应的编码转换。而字符流的实现是基于自动转换的,读取数据时会把数据按照JVM的默认编码自动转换成字符。
1.3字符流:处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。
总结:所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的。
1.4.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串,字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
总结:音频文件、图片、歌曲,就用字节流好点;如果是文本文件,用字符流更好。
2.FILE类的概述
2.1FILE类的属性:
2.2FILE类的构造方法:
2.3FILE类的方法:
2.3.1路径属性的获取
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
//根据文件路径创建一个file实例,路径可以是绝对路径或者相对路径(相对路径是基于该该工程所在的位置)
File f1 = new File("D:/test.txt");//绝对路径
//File f1 = new File("./test.txt");//相对路径
//可以发现绝对路径和相对路径执行的结果是不同的,可以自己编写代码观察
//FILE对象父目录路径
System.out.println(f1.getParent());
//FIle对象的纯文件名称
System.out.println(f1.getName());
//File对象的文件路径
System.out.println(f1.getPath());
//File对象的绝对路径
System.out.println(f1.getAbsolutePath());
//File对象的修饰过的绝对路径
System.out.println(f1.getCanonicalPath());
}
//绝对路径结果:
// D:\
// test.txt
// D:\test.txt
// D:\test.txt
// D:\test.txt
//相对路径结果:
// .
// test.txt
// .\test.txt
// D:\编程\java\javacode\2022-9-28\.\test.txt
// D:\编程\java\javacode\2022-9-28\test.txt
}
2.3.2普通文件的创建
import java.io.File;
import java.io.IOException;
//文件的判断方法和创建
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建FILE文件对象
File f2 = new File("./1.txt");
// File对象描述的文件是否真实存在
System.out.println(f2.exists());
//File对象代表的文件是否是一个目录
System.out.println(f2.isDirectory());
//File对象代表的文件是否是一个普通文件
System.out.println(f2.isFile());
//创建文件基于当前工程所在的目录而创建,当前目录是创建该项目的位置
//目录就是文件夹,不是文件
//根据File对象,自动创建一个空文件。成功创建后返回true
System.out.println(f2.createNewFile());
}
}
2.3.3普通文件的删除
import java.io.File;
//文件的删除
public class Demo3 {
public static void main(String[] args) {
File f3 = new File("./1.txt");
//判定文件是否存在
System.out.println(file.exists());
//删除文件
f3.delete();
//deleteOnExit 进程退出时删除文件
//删除之后,看是否存在
System.out.println(f3.exists());
}
}
2.3.4deleteOnExit的使用
import java.io.File;
import java.io.IOException;
public class Demo4{
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
//程序结束后,文件被删除了 可以自行运行代码观察
2.3.5目录的创建(单级)
//创建文件目录
import java.io.File;
import java.io.IOException;
public class Demo5 {
public static void main(String[] args) throws IOException {
File dir = new File("no-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());
}
}
2.3.6目录的创建(多级)
import java.io.File;
import java.io.IOException;
public class Demo7{
public static void main(String[] args) throws IOException {
File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
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());
}
}
mkdir方法无法创建多级目录,而mkdirs可以解决该问题
import java.io.File;
import java.io.IOException;
public class Demo8 {
public static void main(String[] args) throws IOException {
File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
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());
}
}
2.3.7文件的重命名
import java.io.File;
import java.io.IOException;
//文件的重命名
public class Demo9 {
public static void main(String[] args) throws IOException {
//前提要存在aaa.txt才能重命名成功
File srcFile = new File("aaa.txt");//aaa.txt必须存在
File destFile = new File("bbb.txt");//bbb.txt不存在
System.out.println(file.exists());
System.out.println(dest.exists());
srcFile.renameTo(destFile);
System.out.println(file.exists());
System.out.println(dest.exists());
}
}
2.3.8List方法的使用
import java.io.File;
import java.util.Arrays;
//List的使用
public class Demo10 {
public static void main(String[] args) {
//列出当前目录下的所有文件
File f6 = new File("./IODirectory2");
//File对象代表的目录下的所有文件名
String[] results = f6.list();
System.out.println(Arrays.toString(results));
//File对象代表的目录下的所有文件,以File对象表示
File[] files = f6.listFiles();
}
}
3.文件内容的读写
3.1.FileInputStream使用
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
//文件内容的读(InputStream字节流)
public class Demo11 {
public static void main(String[] args) throws IOException {
//InputStream是一个抽象类,只能构造一个实现该抽象类的类的实例
//以字节流的形式打开文件
//指定文件的路径,相对路径和绝对路径均可,会报文件没找的异常->FileNotFoundException
//类似与C语言中的fOpen方法
InputStream i1 = new FileInputStream("./bbb.txt");
//read函数的三个版本
//read(),读取一个字节的数据,返回-1代表已经完全读完了
//read(byte[] b),最多读取 b.length字节的数据到b中,返回实际读到的数量;-1代表以及读完了
//read(byte[] b,int off, int len),最多读取len - off字节的数据到b中,放在从off开始,返回实际读到的数量;-1代表以及读完了
//使用字节流读文件
while(true){
//读一个字节,读出来的每个字节都是ASCII码值
int b = i1.read();
//read读到文件末尾返回-1
if(b == -1){
break;
}
char res = (char)b;
System.out.print(res);
}
//关闭文件,和打开文件配套使用,注意打开了文件一定要关闭文件
i1.close();
}
}
3.2.FileOutputStream的使用
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//文件的写(OutputStream字节流)
public class Demo12 {
public static void main(String[] args) throws IOException {
//打开要写的文件
//指定的路径可以是相对路径或者绝对路径
OutputStream o1 = new FileOutputStream("./bbb.txt");
//write函数:
//write(int b) 写入要给字节的数据
//write(byte[] b) 将b这个字符数组中的数据全部写入打开的文件中
//write(byte[] b, int off,int len) 将b这个字符数组中从 off 开始的数据写入打开的文件中,一共写len个
//flush函数
//我们知道 I/O 的速度是很慢的,所以,大多的OutputStream为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的
//一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的
//数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。
//写操作,打开文件存在就会把原有文件的内容清空,然后继续写入
o1.write(97);
o1.write(98);
o1.write(99);
//关闭写入的文件
o1.close();
}
}
3.3.FileReader的使用
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
//文件的读(Reader字符流)
public class Demo13 {
public static void main(String[] args) throws IOException {
//文件以字符流的形式打开
Reader r1 = new FileReader("./bbb.txt");
//使用字符流读文件
while(true){
int ret = r1.read();
//读完
if(ret == -1){
break;
}
char ch = (char)ret;
System.out.println(ch);
}
//文件的关闭
r1.close();
}
}
3.4.FileWriter的使用
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
//文件的写(Writer字符流)
public class Demo14 {
public static void main(String[] args) throws IOException {
//字符流的形式打开文件
//会把原有的内容清空,再写入
Writer w1 = new FileWriter("./bbb.txt");
//写入文件
w1.write("hello world");
//关闭文件
w1.close();
}
}
3.5.Scanner读文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
//使用Scanner读文件
public class Demo15 {
public static void main(String[] args) throws IOException {
//Scanner读文本文件
InputStream i1 = new FileInputStream("./bbb.txt");
Scanner scanner =new Scanner(i1);
while(scanner.hasNext()){
System.out.println(scanner.next());
}
//如果在close之前抛出异常就可能会造成文件泄漏
//因此要使用try finally或者try(with resource)去用
scanner.close();
i1.close();
//使用这种版本可以不造成资源泄露
// try(InputStream i1 = new FileInputStream("./bbb.txt");){
// Scanner scanner =new Scanner(i1);
//
// while(scanner.hasNext()){
// System.out.println(scanner.next());
// }
// }
//大家可以自己选择用哪一种方式
}
}
3.6.PrintWriter写文件
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
public class Demo16 {
使用PrinterWriter写文件
public static void main(String[] args) throws IOException {
OutputStream outputStream = new FileOutputStream("./bbb.txt");
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println("hello world");
printWriter.printf("%d\n",10);
printWriter.close();
outputStream.close();
}
}