一、引言
在现代软件开发中,文件操作是一个非常常见且重要的功能。无论是读取配置文件、写入日志文件,还是处理大量的数据,文件操作几乎无处不在。Java 作为一种面向对象的编程语言,提供了强大且灵活的文件操作 API,能够满足各种文件处理需求。本文将详细介绍 Java 中的文件操作,包括文件的创建、读取、写入、删除、目录操作以及文件流的使用等内容。
二、绝对路径和相对路径
在计算机文件系统中,绝对路径和相对路径是指示文件或目录位置的两种不同方式。它们的主要区别在于它们是如何引用文件系统中的位置的。
2.1、绝对路径
绝对路径是从文件系统的根目录(最高级别目录)开始的完整路径,它唯一地标识了文件系统中的文件或目录。绝对路径通常以根目录符号开始,例如在 Unix/Linux 系统中是 /
,在 Windows 系统中是驱动器号如 C:\
。
示例:
- Unix/Linux:
/home/user/documents/report.txt
/var/log/syslog
- Windows:
C:\Users\user\documents\report.txt
D:\projects\project1\main.java
2.2、相对路径
相对路径是相对于当前工作目录的路径。它不以根目录符号或驱动器号开始,而是以当前目录的位置作为参考点。相对路径使用 .
表示当前目录,使用 ..
表示上一级目录。
示例:
- 当前目录是
/home/user
:
documents/report.txt
(相对路径)../etc/config.txt
(上一级目录中的文件)
- 当前目录是
C:\Users\user
:
documents\report.txt
(相对路径)..\Windows\System32\drivers\etc\hosts
(上一级目录中的文件)
2.3、二者区别
- 起始点:
- 绝对路径:从根目录或驱动器号开始。
- 相对路径:从当前工作目录开始。
- 路径的具体性:
- 绝对路径:唯一标识文件或目录的位置,无论当前工作目录是什么。
- 相对路径:依赖于当前工作目录的位置,可能因当前工作目录的不同而指向不同的位置。
- 使用场景:
- 绝对路径:当需要明确指定文件或目录的位置时使用,适用于不确定当前工作目录或需要跨多个目录访问时。
- 相对路径:当在同一目录或相邻目录中进行操作时使用,适用于简化路径表示并增强代码的可移植性。
三、文件操作的基础
在 Java 中,文件操作主要依赖于 java.io
和 java.nio.file
包。java.io
是 Java 早期的文件操作 API,而 java.nio.file
则是 Java 7 引入的新 API,提供了更强大的功能和更高效的文件操作方式。我们将在本文中详细介绍这两种方式。
3.1、打开文件: File
操作
这个操作和 c语言 类似,都是通过我们的 File
来打开一个文件的,代码如下:
File file = new File("需要打开的文件的路径");
通过我们的 File
操作打开一个文件之后,这个类本身有很多方法,如下:
3.2、文件方法
修饰符及返回值类型 |
方法名 |
说明 |
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 |
createNewFile() |
根据 File 对象,自动创建一个空文件。成功创建后返回 true |
Boolean |
delete() |
根据 File 对象,删除该文件。成功删除后返回 true |
void |
deleteOnExit() |
根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行 |
String[] |
list() |
返回 File 对象代表的目录下的所有文件名 |
File[] |
listFiles() |
返回 File 对象代表的目录下的所有文件,以 File 对象表 |
Boolean |
mkdir() |
创建 File 对象代表的目录 |
Boolean |
mkdirs() |
创建 File 对象代表的目录,如果必要,会创建中间目录 |
Boolean |
renameTo(File dest) |
进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
Boolean |
canRead() |
判断用户是否对文件有可读权限 |
Boolean |
canRead() |
判断用户是否对文件有可写权限 |
三、文件内容的读写——数据流
4.1、InputStream
input 这个词大家并不陌生,就是读取嘛,但是得注意,得看我们要站在谁的角度来读取,比如说用户输入了一串信息,如果我们是站在计算机内存的角度的话,就是读取用户输入的信息了,如果是站在用户的角度,我们就是输出信息的那一个了,多数情况下,我们都是站在计算机内存的角度来判断的,这就是为什么 TCP 协议中,我们使用 InputStream
来从服务器读取客户端发过来的请求的原因了。
4.2、OutputStream
Output 翻译过来,就是是输出的意思,当然,和 IntputStream
一样,也得考虑所站位置,比如在上篇博客中,我所说的把 “用户端的请求/服务器的响应” 抛给对方,这个抛其实就是让这份数据远离计算机内存的动作,所以使用 OutputStream
。
4.3、OutputStreamWriter
和 PrintWriter
OutputStreamWriter
是一个字符流类,它将字符流转换为字节流。通常用于将字符数据写入字节输出流,如文件、网络连接等。它的常见用法是将字符编码转换为指定的编码格式。
PrintWriter
是一个更高级的字符流类,提供了便捷的方法来写入格式化的文本数据。它可以直接写入字符数据,并提供了方便的方法如 print()
和 println()
。PrintWriter
可以包裹在 OutputStream
或 Writer
上,提供更丰富的功能。
4.4、四者区别
InputStream vs OutputStream
- InputStream:
- 功能: 用于读取字节数据。
- 类型: 抽象类。
- 用途: 从文件、网络等读取原始字节数据。
- 常用子类:
FileInputStream
、ByteArrayInputStream
。
- OutputStream:
- 功能: 用于写入字节数据。
- 类型: 抽象类。
- 用途: 向文件、网络等写入原始字节数据。
- 常用子类:
FileOutputStream
、ByteArrayOutputStream
。
OutputStreamWriter vs PrintWriter
- OutputStreamWriter:
- 功能: 将字符数据转换为字节数据并写入。
- 类型: 继承自
Writer
类。 - 用途: 用于将字符数据写入字节流(例如文件)时进行字符编码转换。
- 构造参数:
OutputStream
和 字符编码。 - 适用场景: 需要进行字符编码转换时。
- PrintWriter:
- 功能: 便捷地写入格式化的字符数据。
- 类型: 继承自
Writer
类。 - 用途: 提供便捷的方法写入字符、字符串及格式化数据。
- 构造参数:
OutputStream
或Writer
。 - 适用场景: 需要写入格式化的文本数据时。
4.5、总结表格
特性 |
InputStream |
OutputStream |
OutputStreamWriter |
PrintWriter |
功能 |
读取字节数据 |
写入字节数据 |
字符到字节流转换 |
写入格式化字符数据 |
类型 |
抽象类 |
抽象类 |
继承自 |
继承自 |
常用子类或构造参数 |
|
|
|
|
适用场景 |
读取文件、网络等字节数据 |
写入文件、网络等字节数据 |
需要字符编码转换时 |
需要格式化写入文本数据 |
四、总结
在本文中,我们详细探讨了 Java 中的文件操作。首先,我们介绍了绝对路径和相对路径的概念,并通过实例展示了它们的区别和适用场景。接着,我们深入解析了 Java 文件操作的基础,包括文件的创建、读取、写入、删除以及目录操作等内容。通过对 java.io
和 java.nio.file
包的对比,我们了解了不同 API 的特点和使用方式。
特别是对于文件流的使用,我们对 InputStream
、OutputStream
、OutputStreamWriter
和 PrintWriter
进行了深入的讲解和对比分析。InputStream
和 OutputStream
主要用于字节流的读取和写入,而 OutputStreamWriter
则用于将字符流转换为字节流,PrintWriter
提供了便捷的格式化字符输出功能。通过具体的代码示例,我们掌握了这些类的基本用法和适用场景。
五、结语
文件操作在现代软件开发中扮演着重要的角色,掌握这一技能对于提高开发效率和程序的稳定性至关重要。Java 提供了丰富且灵活的文件操作 API,使我们能够轻松应对各种文件处理需求。从基础的文件创建与删除,到复杂的文件流操作,Java 的文件操作功能涵盖了开发过程中可能遇到的各种情况。
通过本文的学习,希望读者能够更加熟练地使用 Java 进行文件操作,为开发高效、稳定的应用程序奠定坚实的基础。无论是处理简单的配置文件,还是进行大规模的数据处理,掌握文件操作的技巧都将使你在开发过程中游刃有余。继续深入学习和实践这些知识,相信你会在编程的道路上走得更远。