文件是用于存储信息的一种数据载体,它可以包含文本、图像、音频、视频等各种形式的数据。文件通常以特定的格式和扩展名表示,常见的文件格式包括.doc/.docx(Word文档)、.xls/.xlsx(Excel表格)、.pdf(便携式文档格式)、.jpg/.png(图片格式)等等。
随着文件越来越多,对文件的系统管理也被提上了日程,如何进行文件的组织呢,一种合乎自然的想法出现了,就是按照层级结构进行组织——也就是我们数据结构中学习过的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory)的概念。(目录==文件夹,是计算机专业术语)
从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描述,而这种描述方式就被称为文件的绝对路径。
Windows都是从“此电脑”开头,表示路径的时候,可以把“此电脑”省略,直接从“盘符”开头。
实际表示路径,是通过一个字符串表示,每个目录之间使用\或者/来分割。
在代码中建议使用/,因为\需要写成\\,需要转义字符。
除了可以从根开始进行路径的描述,我们可以从任意结点出发,进行路径的描述,而这种描述方式就被称为相对路径,相对于当前所在结点的一条路径。
相对路径必须要有几个基准目录,然后从基准目录出发去找到对应的文件。
点(.)是一个特殊符号表示当前目录。点点( . .)表示父目录。
根据其保存数据的不同,也经常被分为不同的类型,我们一般简单的划分为文本文件
和二进制文件,分别指代保存被字符集编码的文本和按照标准格式保存的非被字符集编码过的文件。
文本文件是以纯文本形式存储数据的文件,其中只包含字符或文本信息。它们通常采用ASCII或Unicode编码来表示字符。文本文件可以包含普通文本、代码、配置文件等内容,可以用文本编辑器(如记事本、Sublime Text等)进行打开和编辑。典型的文本文件扩展名包括.txt、.csv、.html等。
二进制文件是以二进制形式存储数据的文件,其中可以包含任意类型的数据,包括文本、图像、音频、视频和程序代码等。二进制文件不直接可读,因为其内容是以二进制编码表示的,需要特定的软件程序来读取和解释文件内容。典型的二进制文件包括图片文件(如.jpg、.png)、音频文件(如.mp3、.wav)、可执行文件(如.exe)等。
简单分辨:
使用快捷键win+R然后输入notepad,拖入一个文件,看的懂得是文本文件,看不懂的是二进制文件。
文件系统操作是指对计算机文件系统进行管理和操作的一系列操作。(例如:创建文件、删除文件、重命名文件、创建目录…)
Java标准库中通过 java.io.File 类来对一个文件和目录路径名进行抽象的表示。
public class FileDemo1 {
public static void main(String[] args) throws IOException {
//File(String pathname):通过将给定的路径字符串转换为抽象路径名来创建的File实例。
File f1 = new File("D:/我的目录/java.txt");
System.out.println(f1);
//File(String parent, String child):从父路径名字符串和子路径名字符串创建的File实例。
//父路径名用路径表示
File f2 = new File("D:/我的目录","java.txt");
System.out.println(f2);
//File(File parent, String child):从父路径名字符串和子路径名字符串创建的File实例。
File f3 = new File("D:/我的目录");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
此时是把java.txt封装成了一个对象,目录下并没有任何内容所以给的路径是不存在的,输出对象后,说明这仅仅是一个抽象路径的表现形式,文件不一定要存在,并且重写了toString方法。
public static void main(String[] args) throws IOException {
//File(String pathname):通过将给定的路径字符串转换为抽象路径名来创建的File实例。
File f1 = new File("D:/我的目录/java.txt");
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());//返回 File 对象的修饰过的绝对路径
}
注意:getCanonicalPath()方法会抛异常
输出结果:
public static void main(String[] args) throws IOException {
File file = new File("helloWorld.txt");
//在相对路径中, ./可以省略
//File file = new File("./helloWorld.txt");
System.out.println(file.exists());//判断 File 对象描述的文件是否真实存在
System.out.println(file.isDirectory());//判断 File 对象代表的文件是否是一个目录
System.out.println(file.isFile());//判断 File 对象代表的文件是否是一个普通文件
//创建文件
file.createNewFile();//根据 File 对象,自动创建一个空文件。成功创建后返回 true
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
注意:createNewFile()方法会抛异常
如果文件不存在,就创建文件,并返回true;如果文件存在,就不创建文件,并返回false。
输出结果:
提示:使用相对路径时./可以省略,调用createNewFile()方法创建的文件在项目目录之下。
file.delete();//根据 File 对象,删除该文件。成功删除后返回 true
public static void main(String[] args) {
File file = new File("java");
//创建一级目录
System.out.println(file.mkdir());
}
如果目录不存在,就创建文件,并返回true;如果目录存在,就不创建文件,并返回false。
public static void main(String[] args) {
File file = new File("JavaEE/IO/课件");
//创建多级目录
System.out.println(file.mkdirs());
}
如果目录不存在,就创建文件,并返回true;如果目录存在,就不创建文件,并返回false。
public static void main(String[] args) {
File file = new File("Java");
String[] result1 = file.list();//返回 File 对象代表的目录下的所有文件名
System.out.println(Arrays.toString(result1));
File[] result2 = file.listFiles();//返回 File 对象代表的目录下的所有文件,以 File 对象表示
System.out.println(Arrays.toString(result2));
}
public static void main(String[] args) {
File src = new File("JavaEE");
File dest = new File("JavaEE初阶");
src.renameTo(dest);//进行文件改名,也可以视为我们平时的剪切、粘贴操作
}
根据文件内容进行读和写:
InputStream是一个抽象类,不能够直接实例化,对文件进行读写操作,我们实例化它的子类FileInputStream。
public static void main(String[] args) throws IOException {
//InputStream是一个抽象类 不能直接实例化,所以实例化它的子类
//通过这个变量就可以对文件进行操作
InputStream inputStream = null;
try {
inputStream = inputStream = new FileInputStream("d:/test.txt");
while (true) {
int b = inputStream.read();
if (b == -1) {
//读到末尾了,结束循环
break;
}
}
inputStream.close();//释放资源,避免文件资源泄露
} catch (IOException e) {
e.printStackTrace();
}
}
上述代码可能会出现一些问题,比如return或者抛异常,就会导致close执行不到,如果close未执行,可能会有非常严重的后果,于是可以把close放到finally里面,但是还是不太优雅。建议使用try with resources写法,带有资源的try操作,会在try代码块结束,自动执行close操作。(因为InputStream实现了一个特殊的借口Closeable)
try (InputStream inputStream = new FileInputStream("d:/test.txt")) {
//读文件
//read一次返回的是一个字节,但是返回值类型是int
while (true) {
int b = inputStream.read();//一次读一个字节
if (b == -1) {
//读到末尾了,结束循环
break;
}
//ASCII码
//System.out.println(b);
//utf8(中文十六进制)
System.out.printf("%x\n",b);
}
}
上述是一次读一个字节的代码,根据文件的里的内容和输出的格式输出。
public static void main(String[] args) {
try (OutputStream outputStream = new FileOutputStream("d:/test.txt")) {
outputStream.write(97);
outputStream.write(98);
outputStream.write(99);
} catch (IOException e) {
e.printStackTrace();
}
}
上述是一次写一个字节的代码。
说明:read和write还可以一次读写多个字节,使用byte[ ]来表示,read操作会尽可能把byte[ ] 给填满,如果读到末尾,返回-1;write操作会把byte[ ] 所有数据都写入文件。
public static void main(String[] args) {
try (Reader reader = new FileReader("d:/test.txt")) {
while (true) {
int b = reader.read();
if (b == -1) {
break;
}
char ch = (char)b;
System.out.println(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
}
上述是一次读一个char。
public static void main(String[] args) throws FileNotFoundException {
try(Writer writer=new FileWriter("d:/test.txt")) {
writer.write('a');
writer.write(' ');
writer.write("hello world");
writer.flush();//不要忘记flush
} catch (IOException e) {
e.printStackTrace();
}
注意: I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。
说明:read方法来读,可以一次读一个char或者char[ ],write方法来写可以一次写一个char或者char[ ]或者String。