Javaee:IO和文件操作
文章目录
- 一、文件
- 1.1文件的概念
- 1.2文件的元信息
- 1.3树型结构组织和目录
- 1.4 文件路径
- 1.5文件的种类
- 二、操作文件(java)
- 2.1 属性
- 2.2构造方法
- 2.3方法
- 文件路径
- 文件判断
- 文件的创建和销毁
- 三、文件的读写操作
- 3.1概念:
- 3.1.1字节流
- InputSteam
- InputStream 的常用方法
- OutputStream
- OutputStream 的常用方法
- 3.1.1字符流
- Reader
- Reader的常用方法
- Writer
- Writer 的常用方法
- Scanner和PrintWriter工具类
- Scanner 读取文件中的字符
- 常用方法
- PrintWriter 写入文件中的字符
- 常用方法
一、文件
1.1文件的概念
广义:在操作系统中会把很多软件资源和硬盘设备抽象成“文件”
狭义:存储在硬盘上的文件
在生活中,大多涉及到的是狭义上的文件,所以这里围绕的也是狭义的文件概念所展开
1.2文件的元信息
文件的元信息:描述文件属性的数据,但不涉及文件的实际内容,元信息帮助操作系统和应用程序管理和识别文件。
常见的文件元信息有
文件名
文件类型
文件大小
创建时间
访问时间
文件权限
…
1.3树型结构组织和目录
在计算机上文件是有操作系统提供的“文件系统”来组织管理的,文件夹或者目录应运而生(用于保存文件的元信息)
Windows上的树型结构组织:
1.4 文件路径
路径用于定位文件或目录在文件系统中的位置,分为两种:
-
绝对路径:从根目录开始的完整路径,如
/home/user/file.txt
(Linux)或C:\Users\user\file.txt
(Windows)。 -
相对路径:相对于当前工作目录的路径,如
./file.txt
或../folder/file.txt
。基准路径的确定,取决于你程序运行的方式
2.1对于命令行操作,当前的目录就是相对路径的基准
2.2对于在idea运行的项目,所在的目录就是基准
2.3 打jar包,取决于当前执行运行命令的目录
1.5文件的种类
从开发的角度分为两类:
-
文本文件:字符集编码的文本和按照标准格式保存的文本(字符串)
-
二进制文件:仅保存二进制数据
注意:所有文件都是二进制的
字符集编码:二进制数据恰好都在码表上能够查到,并且翻译过来的字符能够构成有意义的信息
记事本(所有数据都读到内存中)就是按文本的方式打开,自动进行查码表,翻译
举例:
音频 图片 视频 可执行文件 ——典型的二进制文件
txt 纯文本 .java .c——典型的文本文件
小知识:
文件由于被操作系统进行了管理,所以根据不同的用户,会赋予用户不同的对待该文件的权限,一般地可以认为有可读、可写、可执行权限
二、操作文件(java)
Java中通过 java.io.File 类来对⼀个文件(包括目录)进行抽象的描述。
2.1 属性
修饰符及类型 | 属性 | 说明 |
---|---|---|
static String | pathSeparator | 依赖于系统的路径分隔符,String类型的表示 |
static char | pathSeparator | 依赖于系统的路径分隔符,char类型的表示 |
2.2构造方法
签名 | 说明 |
---|---|
File(File parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File`实例。 |
File(String pathname) | 根据文件路径创建一个新的 File实例,路径可以是绝对路径或者相对路径。 |
File(String parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示。 |
2.3方法
文件路径
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
String | getParent() | 返回File对象的父目录文件路径。 |
String | getName() | 返回File对象的纯文件名称。 |
String | getPath() | 返回File对象的文件路径。 |
String | getAbsolutePath() | 返回File对象的绝对路径。 |
String | getCanonicalPath() | 返回File 对象的修饰过的绝对路径。 |
文件判断
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
boolean | exists() | 判断File对象描述的文件是否真实存在。 |
boolean | isDirectory() | 判断File对象代表的文件是否是一个目录。 |
boolean | isFile() | 判断File 对象代表的文件是否是一个普通文件。 |
boolean | canRead() | 判断用户是否对文件有可读权限。 |
boolean | canWrite() | 判断用户是否对文件有可写权限。 |
文件的创建和销毁
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
boolean | createNewFile() | 根据File对象,自动创建一个空文件。成功创建后返回 true 。 |
boolean | mkdir() | 创建File对象代表的目录。 |
boolean | mkdirs() | 创建File 对象代表的目录,如果必要,会创建中间目录。 |
boolean | delete() | 根据 File对象,删除该文件。成功删除后返回 true 。 |
void | deleteOnExit() | 根据File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行。 |
boolean | renameTo(File dest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作。 |
三、文件的读写操作
3.1概念:
文件的读写操作通常通过流来实现。流是数据传输的抽象概念,分为字节流 和 字符流。
字节流以字节(Byte)为单位处理数据,适合处理二进制文件;
字符流以字符为单位处理数据,适合处理文本文件。
常见问题:一个中文字符对应多少字节?
在UTF-8中对应三个字节,在GBK中占用两个字节
3.1.1字节流
字节流的核心类是 InputStream
和 OutputStream
,它们分别是所有字节输入流和输出流的父类
InputSteam
用于从文件读取数据
InputSteam
是抽象类,不能直接new对象,
提供了一个子类FileInputStream
,可以进行读取操作
InputStream 的常用方法
方法 | 返回值 | 说明 |
---|---|---|
int read() | int | 读取一个字节,返回读取的字节值(0~255),如果到达文件末尾返回 -1 。 |
int read(byte[] b) | int | 读取字节数组,返回实际读取的字节数。 |
int read(byte[] b, int off, int len) | int | 从字节数组的 off 位置开始,读取最多 len 个字节。 |
void close() | void | 关闭输入流,释放资源。 |
实例
import java.io.FileInputStream;
import java.io.IOException;
public class ReadFileExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.txt")) {
int data;
while ((data = fis.read()) != -1) { // 每次读取一个字节
System.out.print((char) data); // 将字节转换为字符输出
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
OutputStream
用于向文件写入数据。
OutputSteam
是抽象类,不能直接new对象
提供了一个子类FileOutputStream
,可以进行读取操作
默认打开一个文件会先清空,若想不清空,在创建对象时需传入参数true
OutputStream 的常用方法
方法 | 返回值 | 说明 |
---|---|---|
void write(int b) | void | 写入一个字节(低 8 位)。 |
void write(byte[] b) | void | 写入字节数组。 |
void write(byte[] b, int off, int len) | void | 从字节数组的 off 位置开始,写入 len 个字节。 |
void flush() | void | 刷新输出流,强制将缓冲区中的数据写入目标。 |
void close() | void | 关闭输出流,释放资源。 |
理解:我们知道I/O的速度是很慢 的,所以,大多的OutputStream
为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域 满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称 为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部 分在缓冲区中。需要在最后或者合 适的位置,调用flush(刷新)操作,将数据刷到设备中。
示例:
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamExample {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output.txt")) {
String content = "Hello, World!";
fos.write(content.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果 output.txt
文件不存在,程序会创建该文件
输出结果:
3.1.1字符流
字符流是 Java 中用于处理 字符数据 的流,它以字符为单位进行读写操作,适合处理文本文件(如 .txt
、.csv
等)。字符流的核心类是 Reader
和 Writer
字符流默认使用 平台默认的字符编码(如 Windows 上是 GBK,Linux 上是 UTF-8)
Reader
Reader
是抽象类,不能直接new对象
提供了子类FileReader
,从文件中读取字符数据
Reader的常用方法
方法 | 返回值 | 说明 |
---|---|---|
int read() | int | 读取一个字符,返回字符的 Unicode 值,如果到达文件末尾返回 -1 。 |
int read(char[] cbuf) | int | 读取字符数组,返回实际读取的字符数。 |
int read(char[] cbuf, int off, int len) | int | 从字符数组的 off 位置开始,读取最多 len 个字符。 |
void close() | void | 关闭输入流,释放资源 |
示例:
import java.io.*;
public class reader {
public static void main(String[] args) throws FileNotFoundException {
try(Reader reader=new FileReader("./text.txt")){
while(true){
int read = reader.read();
if(read==-1){
break;
}
System.out.println((char) read);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
输出结果:
Writer
向文件或目标写入字符数据。
默认打开一个文件会先清空,若想不清空,在创建对象时需传入参数true
Writer
是抽象类,不能直接new对象
提供了子类FileWriter
,从文件中读取字符数据
Writer 的常用方法
方法 | 返回值 | 说明 |
---|---|---|
void write(int c) | void | 写入一个字符。 |
void write(char[] cbuf) | void | 写入字符数组。 |
void write(char[] cbuf, int off, int len) | void | 从字符数组的 off 位置开始,写入 len 个字符。 |
void write(String str) | void | 写入字符串。 |
void write(String str, int off, int len) | void | 从字符串的 off 位置开始,写入 len 个字符。 |
void flush() | void | 刷新输出流,强制将缓冲区中的数据写入目标。 |
void close() | void | 关闭输出流,释放资源。 |
示例:
public class writer {
public static void main(String[] args) {
try(Writer writer=new FileWriter("./output.txt")){
writer.write("HEllo world");
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
注意:操作完成后,务必关闭流以释放资源
使用缓冲流可以提高读写效率
Scanner和PrintWriter工具类
Scanner 读取文件中的字符
Scanner
是一个基于正则表达式的文本扫描器,可以方便地从文件、字符串或输入流中读取数据。
常用方法
方法 | 返回值 | 说明 |
---|---|---|
Scanner(File source) | - | 从文件中创建 Scanner对象。 |
Scanner(InputStream source) | - | 从输入流中创建 Scanner对象。 |
Scanner(String source) | - | 从字符串中创建 Scanner对象。 |
boolean hasNext() | boolean | 判断是否还有下一个输入项。 |
String next() | String | 读取下一个输入项(以空格为分隔符)。 |
String nextLine() | String | 读取下一行内容。 |
int nextInt() | int | 读取下一个整数。 |
double nextDouble() | double | 读取下一个浮点数。 |
void close() | void | 关闭 Scanner对象。 |
使用 Scanner
读取文件
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(new File("input.txt"))) {
while (scanner.hasNextLine()) { // 判断是否还有下一行
String line = scanner.nextLine(); // 读取一行
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
输出结果:
PrintWriter 写入文件中的字符
PrintWriter
是一个字符输出流,用于将格式化的文本写入文件或输出流。它支持自动刷新和格式化输出。
使用 PrintWriter
写入文件
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class PrintWriterExample {
public static void main(String[] args) {
try (PrintWriter writer = new PrintWriter(new File("output.txt"))) {
writer.println("Hello, World!"); // 写入一行
writer.printf("This is a number: %d\n", 123); // 格式化写入
writer.println("这是中文字符。");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
输出结果:
常用方法
方法 | 返回值 | 说明 |
---|---|---|
PrintWriter(File file) | - | 创建 PrintWriter`对象,写入文件。 |
PrintWriter(OutputStream out) | - | 创建 PrintWriter`对象,写入输出流。 |
PrintWriter(Writer writer) | - | 创建 PrintWriter 对象,写入字符流。 |
void print(String s) | void | 写入字符串。 |
void println(String s) | void | 写入字符串并换行。 |
void printf(String format, Object... args) | void | 格式化写入字符串。 |
void flush() | void | 刷新输出流,强制将缓冲区中的数据写入目标。 |
void close() | void | 关闭输出流,释放资源。 |
文件存储在硬盘上
目录也是文件,操作系统通过树形结构组织目录和文件
通过路径识别定位到具体的文件(相对路径和绝对路径)
文件分为文本和二进制