一、引言

在现代软件开发中,文件操作是一个非常常见且重要的功能。无论是读取配置文件、写入日志文件,还是处理大量的数据,文件操作几乎无处不在。Java 作为一种面向对象的编程语言,提供了强大且灵活的文件操作 API,能够满足各种文件处理需求。本文将详细介绍 Java 中的文件操作,包括文件的创建、读取、写入、删除、目录操作以及文件流的使用等内容。


二、绝对路径和相对路径

在计算机文件系统中,绝对路径和相对路径是指示文件或目录位置的两种不同方式。它们的主要区别在于它们是如何引用文件系统中的位置的。

2.1、绝对路径

绝对路径是从文件系统的根目录(最高级别目录)开始的完整路径,它唯一地标识了文件系统中的文件或目录。绝对路径通常以根目录符号开始,例如在 Unix/Linux 系统中是 /,在 Windows 系统中是驱动器号如 C:\

示例:

  1. Unix/Linux:
  • /home/user/documents/report.txt
  • /var/log/syslog
  1. Windows:
  • C:\Users\user\documents\report.txt
  • D:\projects\project1\main.java

2.2、相对路径

相对路径是相对于当前工作目录的路径。它不以根目录符号或驱动器号开始,而是以当前目录的位置作为参考点。相对路径使用 . 表示当前目录,使用 .. 表示上一级目录。

示例:

  1. 当前目录是 /home/user:
  • documents/report.txt(相对路径)
  • ../etc/config.txt(上一级目录中的文件)
  1. 当前目录是 C:\Users\user:
  • documents\report.txt(相对路径)
  • ..\Windows\System32\drivers\etc\hosts(上一级目录中的文件)

2.3、二者区别

  1. 起始点
  • 绝对路径:从根目录或驱动器号开始。
  • 相对路径:从当前工作目录开始。
  1. 路径的具体性
  • 绝对路径:唯一标识文件或目录的位置,无论当前工作目录是什么。
  • 相对路径:依赖于当前工作目录的位置,可能因当前工作目录的不同而指向不同的位置。
  1. 使用场景
  • 绝对路径:当需要明确指定文件或目录的位置时使用,适用于不确定当前工作目录或需要跨多个目录访问时。
  • 相对路径:当在同一目录或相邻目录中进行操作时使用,适用于简化路径表示并增强代码的可移植性。

三、文件操作的基础

在 Java 中,文件操作主要依赖于 java.iojava.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、OutputStreamWriterPrintWriter

OutputStreamWriter 是一个字符流类,它将字符流转换为字节流。通常用于将字符数据写入字节输出流,如文件、网络连接等。它的常见用法是将字符编码转换为指定的编码格式。

PrintWriter 是一个更高级的字符流类,提供了便捷的方法来写入格式化的文本数据。它可以直接写入字符数据,并提供了方便的方法如 print()println()PrintWriter 可以包裹在 OutputStreamWriter 上,提供更丰富的功能。

4.4、四者区别

InputStream vs OutputStream

  • InputStream:
  • 功能: 用于读取字节数据。
  • 类型: 抽象类。
  • 用途: 从文件、网络等读取原始字节数据。
  • 常用子类: FileInputStreamByteArrayInputStream
  • OutputStream:
  • 功能: 用于写入字节数据。
  • 类型: 抽象类。
  • 用途: 向文件、网络等写入原始字节数据。
  • 常用子类: FileOutputStreamByteArrayOutputStream

OutputStreamWriter vs PrintWriter

  • OutputStreamWriter:
  • 功能: 将字符数据转换为字节数据并写入。
  • 类型: 继承自 Writer 类。
  • 用途: 用于将字符数据写入字节流(例如文件)时进行字符编码转换。
  • 构造参数: OutputStream 和 字符编码。
  • 适用场景: 需要进行字符编码转换时。
  • PrintWriter:
  • 功能: 便捷地写入格式化的字符数据。
  • 类型: 继承自 Writer 类。
  • 用途: 提供便捷的方法写入字符、字符串及格式化数据。
  • 构造参数: OutputStreamWriter
  • 适用场景: 需要写入格式化的文本数据时。

4.5、总结表格

特性

InputStream

OutputStream

OutputStreamWriter

PrintWriter

功能

读取字节数据

写入字节数据

字符到字节流转换

写入格式化字符数据

类型

抽象类

抽象类

继承自 Writer

继承自 Writer

常用子类或构造参数

FileInputStream

FileOutputStream

OutputStream + 编码

OutputStreamWriter

适用场景

读取文件、网络等字节数据

写入文件、网络等字节数据

需要字符编码转换时

需要格式化写入文本数据


四、总结

在本文中,我们详细探讨了 Java 中的文件操作。首先,我们介绍了绝对路径和相对路径的概念,并通过实例展示了它们的区别和适用场景。接着,我们深入解析了 Java 文件操作的基础,包括文件的创建、读取、写入、删除以及目录操作等内容。通过对 java.iojava.nio.file 包的对比,我们了解了不同 API 的特点和使用方式。

特别是对于文件流的使用,我们对 InputStreamOutputStreamOutputStreamWriterPrintWriter 进行了深入的讲解和对比分析。InputStreamOutputStream 主要用于字节流的读取和写入,而 OutputStreamWriter 则用于将字符流转换为字节流,PrintWriter 提供了便捷的格式化字符输出功能。通过具体的代码示例,我们掌握了这些类的基本用法和适用场景。


五、结语

文件操作在现代软件开发中扮演着重要的角色,掌握这一技能对于提高开发效率和程序的稳定性至关重要。Java 提供了丰富且灵活的文件操作 API,使我们能够轻松应对各种文件处理需求。从基础的文件创建与删除,到复杂的文件流操作,Java 的文件操作功能涵盖了开发过程中可能遇到的各种情况。

通过本文的学习,希望读者能够更加熟练地使用 Java 进行文件操作,为开发高效、稳定的应用程序奠定坚实的基础。无论是处理简单的配置文件,还是进行大规模的数据处理,掌握文件操作的技巧都将使你在开发过程中游刃有余。继续深入学习和实践这些知识,相信你会在编程的道路上走得更远。

文件操作详解(Java实现)_输入输出流