目录
- 1 IO流原理
- 2 IO流的分类
- 3 输入、输出流代码示例
- 4 小结
- 5 文件在前后台之间传递
在Java中,IO流是一种用于处理输入和输出操作的机制。它提供了一种统一的方式来读取和写入数据,平日开发中在文件读写,网络通信,特定场景的数据库操作,文本处理等地方会频繁使用IO流。
流最主要的功能就是输入、输出。最简单理解:
获取txt文本中内容到程序中处理叫输入流(Input),将程序处理完的内容写到txt文本中叫输出流(Output)。说白了一个负责读一个负责写。
1 IO流原理
IO流是基于流的概念,它将数据的输入和输出看作是一个连续的流。数据从一个地方流向另一个地方,流的方向可以是输入(读取数据)或输出(写入数据)。Java中的IO流分为字节流和字符流两种类型,分别用于处理字节数据和字符数据。
IO流的原理是通过流的管道将数据从源头传输到目标地。源头可以是文件、网络连接、内存等,而目标地可以是文件、数据库、网络等。IO流提供了一组丰富的类和方法来实现不同类型的输入和输出操作。
2 IO流的分类
Java中的IO流可以按照数据的类型和流的方向进行分类。
- 按数据类型分类
- 字节流(Byte Stream):以字节为单位读写数据,适用于处理二进制数据,如图像、音频、视频等。常见的字节流类有
InputStream
和OutputStream
。 - 字符流(Character Stream):以字符为单位读写数据,适用于处理文本数据。字符流会自动进行字符编码和解码,可以处理多国语言字符。常见的字符流类有
Reader
和Writer
。
- 字节流(Byte Stream):以字节为单位读写数据,适用于处理二进制数据,如图像、音频、视频等。常见的字节流类有
- 按流的方向分类
- 输入流(Input Stream):用于读取数据。输入流从数据源读取数据,如文件、网络连接等。常见的输入流类有FileInputStream、ByteArrayInputStream、SocketInputStream等。
- 输出流(Output Stream):用于写入数据。输出流将数据写入到目标地,如文件、数据库、网络等。常见的输出流类有FileOutputStream、ByteArrayOutputStream、SocketOutputStream等。
分类继承结构图如下:
3 输入、输出流代码示例
开发过程中使用比较多的是InputStream
和OutputStream
,这两个类层级较高的父类,是抽象类,通常会创建其下的子类。
-
InputStream
ByteArrayInputStream
、StringBufferInputStream
、FileInputStream
是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。下面一以FileInputStream
和FileOutputStream
为例。 -
OutputStream
ByteArrayOutputStream
、FileOutputStream
是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,
-
FileInputStream案例
字节输入流的步骤如下:
- 创建流对象
- 创建一个缓存字节的容器数组
- 读取数据
- 操作保存数据的数组
- 关闭流
public void input() throws IOException { String fileName="D:\\file\\测试.txt"; File file = new File(fileName); InputStream in = new FileInputStream(file); byte[] b = new byte[1024]; //Reads some number of bytes from the input stream and stores them into the buffer array b. in.read(b); in.close(); System.out.println(new String(b)); }
可以将文件转成流后,调用
read()
方法将流读取出来存到字节数组中,所存的字节数组作为参数传入,可以看到打印的正是文件中所写的内容
-
FileOutputStream案例
将输出流写入文件的步骤如下:
- 选择流:创建流对象
- 准备数据源,把数据源转换成字节数组类型
- 通过流向文件当中写入数据
- 刷新流
- 关闭流
public void output() throws IOException { String s = "hello"; OutputStream out = new FileOutputStream("D:\\file\\输出.txt"); byte[] bytes = s.getBytes(); out.write(bytes); out.close(); }
OutputStream是字节流,所以要先将输出内容转成字节数组,在通过write(byte [])方法写出去。
不要混淆了InputStream/OutputStream和File的功能
前两者只负责往文件中读写数据,只是以一种流的形式对数据内容进行多元化的操作,至于文件的生成,命名等一系列和文件整体相关的操作,是
File
类的责任。
还比较常用的是BufferInputStream
缓冲流
缓冲流的好处:
缓冲流内部包含一个缓冲区域,默认8kb,每一次程序调用read方法其实都是从缓冲区域当中读取内容,如果读取失败就说明缓冲区域当中没有内容,那么就从数据源当中读取内容,然后会尽可能读取更多的字节放入到缓冲区域当中,最后缓冲区域当中的内容,会全部返回给程序。从缓冲区读取数据会比直接从数据源读取数据的速度快,效率也更高,性能更好。
简单说:
没有缓存区,那么每read一次,就会发送一次IO操作;
有缓存区,第一次read时,会一下读取x个字节放入缓存区,然后后续的read都会从缓存中读取,当read到缓存区末尾时,会再次读取x个字节放入缓存区。
处理流处理数据和节点流处理数据的方法基本上完全相同。
4 小结
流的读写其实很简单,且步骤比较固定,但是将文件转成流之后可操作性就变得很大很大。
一不可能直接对文件进行修改,但流是通用的,改变流的内容、形式再输出给文件,展示出来的效果就发生改变;
二是文件有可能很大,不可能将这么大的文件在网络上传递,就要转成流,一点一滴连续的传输。这就是为什么下载或上传过程中可以随意暂停、开始也不影响,因为只要保证这些点滴最终拼起来是完整的即可。
本文只演示了最简单的对txt文本格式的数据读写,原理是一样的,每一位数据都有唯一对应的字节码,可以从数据转成字节、从字节转成数据。所以才叫字节流。
但文件个格式多种多样,输出前必须要转成相同格式的流,就是在InputStream
和OutputStream
操作之间按照自己需求自定义操作。
5 文件在前后台之间传递
开发过程中经常需要将文件从前台传递给后台或后台传给前台,这步操作怎么实现?