怒肝两万字 Java 中的 IO(详细篇)

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

文章目录

Java IO 的演变之路

I/O模型:就是用什么样的通道或者说是通信模式和架构进行数据的传输和接受,很大程度上决定了程序通信的性能,在Java 当中一种支持 3 种 IO模型。

BIO、NIO、AIO

在实际通信需求下,要根据不同的业务场景和性能需求决定选择不同的 IO 模型。

I/O 模型

Java BIO:同步并阻塞的(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有链接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销。

BIO 方式主要适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4之前的唯一选择,但程序方面简单易理解。

Java NIO:同步非阻塞。服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求就进行处理。

NIO 方式主要适用于连接数目比较多且连接数据比较短(轻操作)的架构。比如:聊天服务器,弹幕系统,服务器间通信,JDK 1.4 开始支持这方面的事了。

Java AIO:异步非阻塞(NIO.2),服务器实现模式为一个有效情趣一个线程,客户端的 I/O 请求都是由 OS 先完成了再通知服务器应用去启动线程进行处理,一般适用于连接数目较多并连接时间较长的应用。

AIO 方式主要适用于连接数目多且连接数据比较长(重操作)的结构。比如:相册服务器,充分调用 OS 参与并发操作,编程比较复杂,JDK 7天之后开始支持。

基本介绍以及工作机制

Java BIO 就是传统的 Java IO 编程,其相关的类型和接口是在 java.io 包中。

BIO(blocking I/O)同步阻塞,服务器实现模式为一个连接一个线程,即客户端游连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销,可以通过线程池机制来进行改善(实现多个客户连接服务器)

网络编程的基本模型是什么 Client/Server 模型,也就是两个进程之间进行相互的通信,其中服务端提供位置信息(绑定 IP 地址和端口),客户端通过连接操作向服务端监听的端口地址发起连接请求,基于 TCP 协议下进行三次握手连接,连接成功后,双方通过网络套接字(Socket)进行通信。

传统的同步阻塞模型还在开发中,服务器端 ServerSocket 负责绑定 IP 地址,启动监听端口;客户端 Socket 负责发起连接操作。连接成功后,双方通过输入和输出流进行同步阻塞式通信。

基于 BIO 模式下的通信,客户端-服务端是完全同步的,完全耦合的。

BIO 模式下多发和多收模式

代码演示,代码说明一切

服务端:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 * 可以反复的接收消息,客户端可以反复的发送消息
 */
public class Server {
 
    public static void main(String[] args) {
 
        try {
 
            System.out.println("===服务端启动===");
            //1.定义一个ServerSocket对象进行服务端的端口注册
            ServerSocket ss = new ServerSocket(9999);
            //2. 监听客户端的Socket连接请求
            Socket socket = ss.accept();
            //3.从socket管道中得到一个字节输入流对象
            InputStream inputStream = socket.getInputStream();
            //4.把字节输入改为字符输入流
            InputStreamReader reader = new InputStreamReader(inputStream);
            //4.把字符输入流包装成一个缓存字符输入流
            BufferedReader br = new BufferedReader(reader);

            String msg;
            while ((msg = br.readLine()) != null) {
 
                System.out.println("服务端接收到:" + msg);
            }
        } catch (Exception e) {
 
            e.printStackTrace();
        }
    }
}

客户端:

import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * 客户端
 * 用来发送数据
 */
public class Client {
 
    public static void main(String[] args) {
 
        try {
 
            //1.创建Socket对象请求服务端的连接
            Socket socket = new Socket("127.0.0.1",9999);
            //2.从Socket对象中获取一个字节输出流
            OutputStream os = socket.getOutputStream();
            //3.把字节输出流包装成一个打印流
            PrintStream ps = new PrintStream(os);
            Scanner sc = new Scanner(System.in);

            while (true) {
 
                System.out.print("请说:");
                String msg = sc.nextLine();
                ps.println(msg);
                ps.flush();
            }

        } catch (Exception e) {
 
            e.printStackTrace();
        }
    }
}

在上面的通信当中,服务端会一直等待客户端的消息,如果客户端没有进行消息的发送,服务端将会一直处于阻塞状态。

同时服务端是按照行获取信息的,这就意味着客户端也必须按照进行消息的发送,否则服务端将进入等待消息的阻塞状态。

同时在这,若先关闭客户端,那么服务端就将会报错。Connection reset(连接重置的意思) 

BIO 模式下接受多个客户端

上面的是一个服务端只能结束一个客户端的通信请求,那么如果服务端需要很多个客户端的信息通信请求应该如何处理,在这个时候我们就可以引入线程,也就是说客户端没发起一个请求,服务端就创建一个新的线程来处理这个客户端的请求,这样就实现了一个客户端一个线程的模型了。

代码说明:

服务端代码:

import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 * 接受客户端发来的请求
 * 因为服务端要求接受多个客户端的连接,所以以现场操作进行
 */
public class Server {
 
    public static void main(String[] args) {
 
        try {
 
            System.out.println("===服务端启动===");
            //1.注册端口
            ServerSocket ss = new ServerSocket(9999);
            //2.定义一个死循环,负责不断的接收客户端的Socket的连接请求
            while (true) {
 
                // 阻塞式的,当遇到一个客户端请求连接,通过,当没有的时候,阻塞
                Socket socket = ss.accept();
                //3.创建一个独立的线程来处理与这个客户端的socket通信的具体需求
                new ServerThread(socket).start();
            }
        } catch (Exception e) {
 
            e.printStackTrace();
        }
    }
}

服务端需要接受多个客户端,就要开启多线程。多线程代码:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * 服务端创建的线程,服务端后执行的东西主要就是在这进行执行
 */
public class ServerThread extends Thread {
 
    private Socket socket;

    public ServerThread(Socket socket) {
 
        this.socket = socket;
    }

    @Override
    public void run() {
 
        // 在这执行具体的客户端的具体操作
        try {
 
            //从 socket 对象中得到字节的输入流
        
JAVA基础】Java IO详解 Java IO 阅读详情

相关推荐

Java IO详解

IO即Input和Output,即输入和输出。这里的输入和输出都是相对于内存来说的。

liwangcuihua的博客 7751

猿创征文|Java中的IO流大家族 (两万详解)

IO流有多种分类方式:一种方式是按照流的方向进行分类:以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read)。从内存中出来,叫做输出(Output)。或者叫做写(Write) 另一种方式是按照读取数据方式不同进行分类: 有的流是按照节的方式读取数据,一次读取1个节byte,等同于一次读取8个二进制,这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频。 假设文件file1.txt,采用节流的话是这样读的: a中国bc张三fe 第一次读:一个

YOU__FEI的博客 3364

JSD-2204-API-JavaIO-Day02

API-JavaIO

TheNewSystrm的博客 813

JavaIO流详解

JavaIO流详解

游手好闲 1万+

Java IO学习和总结(超详细

Java IO详细解读

我的青春一去不复返 7262

JAVA IO 详细介绍】

Java IO

weixin_44273248的博客 3680

Java IO(非常详细)

注:本文章部分图片可能来源网络,侵删。 关于IO会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点。知识点虽然不难但平常经常容易搞混,特此Mark下,与君共勉。 文章目录1、同步IO1.1 阻塞IO1.2 非阻塞IO1.3 IO多路复用(!)1.3.1 select1.3.2 poll1.3.3 epoll2、异步IO3、Java IO3.1 BIO3.2 NIO3.3 AIO 1、同步IO 1.1 阻塞IO 如图所示,阻塞式IO情况下,当系统调用read.

荷兰豆_的博客 9757

<<两万通关Java IO流>>

Java IO流详解介绍

m0_62547912的博客 715

Java中的IO详细笔记

IO流(Input/Output Stream)是Java中用于处理输入和输出数据传输的抽象概念。它将数据的传输过程形象地比喻为"流水",数据如同水流一样从一个位置流向另一个位置。IO流体系| |节流 符流| || | | |

qq_38955667的博客 1460

Java8—Stream流式编程、Optional容器的详细介绍【两万

基于Java8详细介绍了Stream流的含义和大部分API方法的使用,以及Optional容器、并行流等Java8的新特性!

终生学习践行者 4651

Java 中的阻塞 IO 和非阻塞 IO

IO(输入输出)操作是一个基础而又关键的部分。在 Java 中,处理 IO 通常涉及到阻塞 IO 和非阻塞 IO 两种模式。本文将介绍这两种模式的概念、特点以及在 Java 编程中的应用场景与区别。

✨ 欢迎来到【Seal ^_^ 的CSDN博客】!✨ 5858

Java中的IO流(最详细解说)

IO流一、File类的使用1.常用构造器2.路径分隔符3.常用方法二、IO流原理及流的分类1.Java IO原理三、流的分类1.输入流(1)InputStream & Reader(2)InputStream(3)Reader2.输出流(1)OutputStream & Writer(2)OutputStream(3)Writer3.节点流(1)读取文件1.符读取FileReader (read(char[] cbuf))2.节读取FileInputStream (read(byte

spade_Kwo的博客 9589

一万讲解Java中的IO流——包含底层原理

最难不过坚持

2401_84927284的博客 1044

【Servlet进阶】暴两万五千助你通关Servlet

前言 在之前我们已经学过Servlet初级入门的一部分内容了,今天我们继续来学习Servlet,但是你如果对Servlet还不了解的话那么建议你先去看一下我之前写过的入门的部分。 传送门:【Servlet入门】一文章让你快速入门 传送门:【JSP入门】只知道HTML却不知道JSP? 接下来我们就正式来学习今天的内容吧! 目录前言请求与响应Get与Post请求请求的结构响应的结构Servlet的核心对象JSP的九大内置对象 请求与响应 我们之前学过Servlet最主要的作用就是处理客户端的请求,并向客户端作

apple_51673523的博客 5099

Java——IO流超详细总结

该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架。 在初学Java时,IO流是我遇到的一个很头疼的东西,Java IO 体系看起来类很多,感觉很复杂,但其实是 IO 涉及的因素太多了。在设计 IO 相关的类时,编写者也不是从同一个方面考虑的,所以会给人一种很乱的感觉,并且还有设计模式的使用,更加难以使用这些 IO 类,所以特地对 JavaIO 做一个总结。 1|0

ywb201314的专栏 6623

这些Java常用类,你必须要学会,还不快快收藏?(近两万详细介绍)

本文介绍了Java常用类,包括包装类、Math、String类、可变符序列和时间日期,并举例说明。欢迎大家交流讨论

一入大数据深似海?别怕!“数据极客圈”就是你的救生圈,走对圈子跟对人,趣析数据、畅聊趋势,快进圈子! 4788

Java基础IO流,动力节点老杜详细笔记

详细讲解IO流,主要聚焦如何使用、掌握常用方法等

qq_45769329的博客 1672

Java基础 IO

I 表示intput,是数据从硬盘进内存的过程,称之为读。O 表示output,是数据从内存到硬盘的过程。称之为写IO的数据传输,可以看做是一种数据的流动,按照流动的方向,以内存为参照物,进行读写操作内存在读,内存在写1、节点流可以从一个特定的数据源读写数据,如:FileReader、FileWriter2、处理流(也叫包装流)是连接在以存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,更加灵活多变。如BufferReader、BufferWriter。计算机文件、文件。

分享思想,留下痕迹。 1074
上一篇: SpringCloud系列:服务网关组件Gateway
下一篇: Redis分布式锁升级:RedLock+SpringBoot
头顶假发
博客等级 码龄4年 93粉丝 574原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值