一、Java IO 概述
1、IO
在 Java 中,IO(Input/Output,输入/输出) 是步调与外部资源(如文件、网络、内存、控制台等)举行数据交互的核心机制。
全部IO 都是通过输入/输出流来处理处罚的。这些流按照同一的方式来处理处罚与各种数据源之间的通讯,比方文件、网络毗连或内存块。
Java 通过一套标准库(java.io 和 java.nio)提供了丰富的类来处理处罚差别范例的 IO 操纵。
2、IO流的分类
流是数据的载体。
- 按数据方向
- 输入流(Input Stream):从数据源(如文件、网络等)读取数据。
- 输出流(Output Stream):向目的(如文件、网络等)写入数据。
- 按数据范例
- 字节流(Byte Streams):以字节(8位)为单位操纵,处理处罚全部二进制数据(如图片、音频、视频等)。
- 基类:InputStream 和 OutputStream。
- 字符流(Character Streams):以字符(16位Unicode)为单位操纵,专门处理处罚文本数据。
- 按功能
- 节点流(Node Streams):直接操纵数据源(如文件流)。
- 处理处罚流(Processing Streams):对现有流举行包装,加强功能(如缓冲、转换格式)。
3、IO计划模式
Java IO 通过装饰器模式扩展流的功能,比方:
- 缓冲功能:BufferedInputStream、BufferedWriter。
- 数据转换:InputStreamReader(字节转字符)、DataInputStream(处理处罚根本数据范例)。
4、核心类与常用流
(1)字节流
- InputStream(输入流)
- FileInputStream:从文件读取字节。
- ByteArrayInputStream:从字节数组读取。
- BufferedInputStream:提供缓冲功能,淘汰IO次数。
- DataInputStream:读取Java根本数据范例(如int、double)。
- ObjectInputStream:反序列化对象(需实现Serializable接口)。
- OutputStream(输出流)
- FileOutputStream:向文件写入字节。
- ByteArrayOutputStream:写入字节数组。
- BufferedOutputStream:缓冲输出流。
- DataOutputStream:写入Java根本数据范例。
- ObjectOutputStream:序列化对象。
(2)字符流
- Reader(字符输入流)
- FileReader:读取文本文件。
- BufferedReader:提供缓冲功能,支持readLine()逐行读取。
- InputStreamReader:将字节流转换为字符流(可指定编码)。
- Writer(字符输出流)
- FileWriter:写入文本文件。
- BufferedWriter:缓冲输出流。
- OutputStreamWriter:将字符流转换为字节流(可指定编码)。
(3)转换流
- InputStreamReader 和 OutputStreamWriter:用于字节流与字符流的转换,支持字符编码(如UTF-8、GBK)。
5、示例
(1)文件读写
- 字节流示例(复制文件):
- try (FileInputStream fis = new FileInputStream("input.jpg");
- FileOutputStream fos = new FileOutputStream("output.jpg")) {
- byte[] buffer = new byte[1024];
- int bytesRead;
- while ((bytesRead = fis.read(buffer)) != -1) {
- fos.write(buffer, 0, bytesRead);
- }
- }
复制代码 - 字符流示例(逐行读取文本):
- try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
- String line;
- while ((line = br.readLine()) != null) {
- System.out.println(line);
- }
- }
复制代码 (2)对象序列化
- // 序列化
- try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.obj"))) {
- oos.writeObject(new Person("Alice", 30));
- }
- // 反序列化
- try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.obj"))) {
- Person p = (Person) ois.readObject();
- }
复制代码 (3)缓冲流提升性能
- // 使用缓冲流复制文件(效率更高)
- try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
- int data;
- while ((data = bis.read()) != -1) {
- bos.write(data);
- }
- }
复制代码 6、应用场景
IO流紧张用于处理处罚输入和输出操纵,实用于以了局景:
- 文件读写:通过IO流可以读取和写入文件中的数据,如读取设置文件、写入日记等。
- 网络通讯:通过IO流可以举行网络数据的传输和罗致,如Socket通讯、HTTP哀求等。
- 数据库操纵:通过IO流可以将数据读取到内存中,或将内存中的数据写入到数据库中。
- 文本处理处罚:通过IO流可以读取和写入文本文件,举行文本处理处罚和操纵。
二、Linux 网络IO模子
Linux 的内核将全部外部装备都看做一个文件来操纵,对一个文件的读写操纵会调用内核提供的体系下令,返回一个 file descriptor(fd,文件形貌符)。而对一个 socket 的读写也会有相应的形貌符,称为socketfd(socket形貌符),形貌符就是一个数字,它指向内核中的一个布局体(文件路径,数据区等一些属性)。
根据 UNIX 网络编程对 I/O 模子的分类,UNIX 提供了 5 种 I/O 模子,分别如下:
(1) 壅闭 I/O 模子:最常用的 I/O 模子就是壅闭 I/O 模子,缺省环境下,全部文件操纵都是壅闭的。以套接字接口为例来讲授此模子:在进程空间中调用recvfrom,其体系调用直到数据包到达且被复制到应用进程的缓冲区中大概发生错误时才返回,在此期间不绝会等待,进程在从调用 recvfrom 开始到它返回的整段时间内都是被壅闭的,因此被称为阻寨 I/O 模子,如图 1-1 所示:
(2)非壅闭 I/0 模子:recvfrom 从应用层到内核的时间,如果该缓冲区没有数据的话就直接返回一个 EWOULDBLOCK 错误,一样平常都对非壅闭 I/O 模子举行轮询查抄这个状态,看内核是不是有数据到来。如图1-2所示。
(3)I/0 复用模子:Linux 提供 select/poll,进程通过将一个或多个 fd 通报给 select 或poll 体系调用,壅闭在 select 操纵上,如许 select/poll 可以帮我们侦测多个 fd 是否处于停当状态。select/poll 是次序扫描 fd 是否停当,而且支持的 fd 数量有限,因此它的使用受到了一些制约。Linux 还提供了一个 epoll 体系调用,epoll 使用基于变乱驱动方式代替次序扫描,因此性能更高。当有fd停当时,立即回调函数rollback。如图 1-3 所示。
(4)信号驱动 I/0 模子:起首开启套接口信号驱动 I/O 功能,并通过体系调用 sigaction实验一个信号处理处罚函数(此体系调用立即返回,进程继承工作,它好坏壅闭的)。当数据准备停当时,就为该进程天生一个 SIGIO 信号,通过信号回调关照应用步调调用 recvfrom来读取数据,并关照主循环函数处理处罚数据。如图 1-4所示。
(5)异步 I/0:告知内核启动某个操纵,并让内核在整个操纵完成后(包罗将数据从内核复制到用户自己的缓冲区)关照我们。这种模子与信号驱动模子的紧张区别是:信号驱动 I/O 由内核关照我们何时可以开始一个 I/O 操纵;异步 I/O 模子由内核关照我们 I/O操纵何时已经完成。如图 1-5 所示。
十、资料
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |