目录
1. 相对论理解 I/O 流
**输入/输出流(I/O Stream)**是计算机程序中的核心概念之一,它涉及到数据的读取(输入)和写入(输出)。为了更好地理解I/O流的工作原理,我们可以借助物理学中的相对论和流体流动来做比喻。
I/O 流的基本概念
在字面上,Stream指的是具有方向性的流动,如水流、电流等,它强调的是过程。在计算机中,I/O流通常指的是数据在计算机中从输入源(如键盘、文件等)流向输出目标(如屏幕、文件等)的一种过程。
相对论视角下的 I/O 流
从相对论的角度来看,I/O流的输入与输出具有相对性。不同的参照系会导致不同的流动方向和定义:
-
冬季旱季的流动
:
- 假设我们站在支流的角度,支流中的水从支流流出,进入大江(如长江)。这里,支流是“输出”的源头,长江是“输入”的目标。
-
夏季雨季的流动
:
- 当进入雨季时,支流可能变成了接收的源头,反过来,长江的水流将从大江流向支流,这时候长江变成了输出源,支流变成了输入目标。
类比到 I/O 流:
- 输入流(Input Stream):就像支流对长江来说,是一个“输入”源。计算机中的输入流指的是从外部设备(如文件、键盘、网络)读取数据的过程。
- 输出流(Output Stream):类似于长江输出水流的过程,输出流是将数据从程序写入外部设备(如屏幕、文件、网络)的过程。
管道的角色
就像流体流动需要管道来引导水流一样,I/O流也需要管道来传递数据。管道可以是文件流、网络流、缓冲流等,它们为数据流动提供了“通道”。
参照系的选择
-
谁是输入,谁是输出
:在不同的程序设计环境和任务中,输入和输出的角色是相对的。就像你可以选择站在支流或长江的角度看待水的流动一样,数据的来源和去向也依赖于你的视角。
- 输入流:表示从外部源读取数据(比如从文件中读取数据)。
- 输出流:表示将数据写入到外部目标(比如将数据写入文件)。
总结:
I/O流是一个双向的过程,正如流体流动在不同环境下的表现那样,输入和输出是相对的,取决于程序的需求和任务。理解了这个类比,可以帮助我们更好地理解计算机中的I/O流动。
3. 图解 I/O 流
I/O 流的核心在于数据在程序与外部设备之间的流动,站在不同的视角,输入和输出的方向是不同的。为了更清楚地理解 I/O 流动,我们可以通过图示的方式来帮助理解。
1. 写数据(Program → Data)
-
图示:
Program ---> Data (Write data) (Input to data source) -
说明:
- 程序向数据源写数据。从程序的角度,数据是从程序流向数据源(如文件、数据库、网络等)。这时程序执行的是写操作,数据源执行的是输入操作。
- 这个过程称为“输出”(output),因为程序将数据输出到外部设备或文件系统。对于外部数据源来说,这就是输入(input)。
-
示例:
- 程序通过文件输出流将数据写入文件中。
- 程序通过网络连接将信息发送到服务器。
2. 读数据(Data → Program)
-
图示:
Data ---> Program (Read data) (Input to program) -
说明:
- 数据从数据源流入程序。此时数据源(如文件、数据库、网络等)提供数据给程序。程序执行读取操作,而数据源执行输出操作。
- 这个过程被称为“输入”(input),因为程序正在从数据源读取数据。对于数据源而言,这时是输出(output),因为它将数据提供给程序。
-
示例:
- 程序通过文件输入流从文件中读取数据。
- 程序通过网络连接从服务器获取数据。
程序角度的理解:
从程序的角度来看,所有的操作都是围绕“输入”和“输出”进行的:
- 输出:当程序将数据传输到外部设备时,程序执行输出操作。
- 输入:当程序从外部设备获取数据时,程序执行输入操作。
然而,站在数据源的角度,输入和输出的角色是互换的。
- 数据源的输入:程序写入数据时,数据源是输入。
- 数据源的输出:程序读取数据时,数据源是输出。
总结:
I/O 流的核心概念就是数据流动的方向,程序与数据源之间的操作方向是相对的,取决于我们站在程序还是数据源的角度来看。
4. 俩亲爹:InputStream 和 OutputStream
在 Java 的 I/O 流中,InputStream 和 OutputStream 是两个非常重要的类,它们是所有字节流的父类,分别负责数据的输入和输出。
1. InputStream:数据读取的管理者
InputStream 是所有输入流的父类,专门负责读取数据。通过继承 InputStream 的子类(如 FileInputStream, BufferedInputStream 等),我们可以从各种数据源(如文件、网络、内存)中读取数据。
-
常用方法:
int read():从输入流中读取一个字节的数据,返回值是该字节的整数表示,读到文件末尾时返回-1。int read(byte[] b):将输入流中的字节读入一个字节数组。void close():关闭流,释放资源。
-
示例:
FileInputStream fis = new FileInputStream("example.txt"); int data = fis.read(); while (data != -1) { System.out.print((char) data); data = fis.read(); } fis.close();
2. OutputStream:数据写入的管理者
OutputStream 是所有输出流的父类,专门负责将数据写入目标设备。通过继承 OutputStream 的子类(如 FileOutputStream, BufferedOutputStream 等),我们可以将数据写入文件、网络等目标。
-
常用方法:
void write(int b):将一个字节的数据写入输出流。void write(byte[] b):将字节数组的数据写入输出流。void close():关闭流,释放资源。
-
示例:
FileOutputStream fos = new FileOutputStream("example.txt"); fos.write(65); // 写入一个字节数据,ASCII 65对应字母 'A' fos.close();
3. InputStream 与 OutputStream 的对比:
- 职责:
InputStream管理 读取 操作。OutputStream管理 写入 操作。
- 数据方向:
- 在
InputStream中,数据是从外部流向程序(输入)。 - 在
OutputStream中,数据是从程序流向外部目标(输出)。
- 在
4. 继承结构:
InputStream 和 OutputStream 是许多具体输入流和输出流类的父类。通过它们,Java 提供了灵活的字节流处理方式。例如:
- 字节输入流:
FileInputStreamByteArrayInputStreamObjectInputStream
- 字节输出流:
FileOutputStreamByteArrayOutputStreamObjectOutputStream
总结:
InputStream负责 读取 数据。OutputStream负责 写入 数据。- 它们是 Java I/O 流的核心父类,其他字节流都继承自这两个类。
5. 使用 FileInputStream 进行字节流文件读取
FileInputStream 是 Java 中用于读取文件字节流的类。它用于从文件中读取数据流,适合读取原始字节数据(如图片、音频等)。以下是你提供的代码,使用 FileInputStream 逐字节读取文件内容并打印到控制台。
代码解析:
import org.junit.Test;
import java.io.FileInputStream;
import java.io.IOException;
public class DemoTest {
@Test
public void inputFile() throws IOException {
// 创建FileInputStream对象,指定要读取的文件路径
FileInputStream fileInputStream = new FileInputStream("file/1.txt");
int filereading = 0;
// 使用read()方法读取文件,直到文件末尾(返回-1)
while(filereading != -1) {
// .read()方法按字节读取文件内容,返回值是字节对应的整数。如果读取到的是文本文件,它会按ASCII码值返回字节。
filereading = fileInputStream.read();
// 将读取的字节值转换为字符并打印(char对应ASCII值)
System.out.println((char)filereading);
}
// 关闭输入流,释放资源
fileInputStream.close();
}
}
代码详细解释:
FileInputStream fileInputStream = new FileInputStream("file/1.txt");- 通过
FileInputStream构造函数打开指定的文件"file/1.txt"。请确保文件路径正确,且文件存在。
- 通过
filereading = fileInputStream.read();read()方法读取文件的下一个字节并返回它的值(对应于字节的 ASCII 值)。如果文件读取完毕,read()返回-1,表示文件结束。
System.out.println((char)filereading);- 将读取到的字节值转换为字符并打印。由于 ASCII 字符编码,
(char)转换后显示为对应的字符。
- 将读取到的字节值转换为字符并打印。由于 ASCII 字符编码,
fileInputStream.close();- 使用完输入流后,必须调用
close()方法关闭文件流,以释放系统资源。
- 使用完输入流后,必须调用
注意事项:
- 字符编码: 上述代码按字节读取文件并直接转换为字符,适用于文本文件。如果是二进制文件(如图片、音频等),不应将其转换为字符,而应按字节处理。
- 文件路径: 文件路径
"file/1.txt"应根据项目的目录结构调整。如果文件位于项目根目录下的file文件夹内,代码路径是正确的。 - 异常处理: 代码中的
throws IOException说明了方法可能抛出IOException,实际开发中可以使用try-catch捕获并处理异常。
优化建议:
为了提高性能,可以使用 BufferedInputStream 来包装 FileInputStream,以便一次性读取多个字节。
6. 使用 FileOutputStream 进行字节流文件写入
FileOutputStream 是 Java 中用于写入文件字节流的类。它适合用于将原始字节数据(如文本、音频、图片等)写入文件。以下是你提供的代码,演示了如何使用 FileOutputStream 将字节数据写入文件。
代码解析:
import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
public class DemoTest {
// 方式 1:使用 .write() 方法直接写入字节数组
@Test
public void outputFile() throws IOException

最低0.47元/天 解锁文章
5890

被折叠的 条评论
为什么被折叠?



