北京网站推广优化/成品影视app开发
一、简介
1.1 BIO概述
BIO(Blocking I/O),即同步阻塞IO(传统IO)。
BIO 全称是 Blocking IO,同步阻塞式IO,是JDK1.4之前的传统IO模型,就是传统的 java.io 包下面的代码实现。
服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如下图所示:
在 BIO 模型下,应用程序会在进行 I/O 操作时阻塞当前线程,直到 I/O 操作完成。例如,执行一个读取操作时,线程会等待,直到数据从磁盘或网络中完全读取完成。在这个过程中,线程不能做其他任务,必须等待 I/O 操作的结果。
BIO 模型的特点
- 同步阻塞:
- 当线程进行 I/O 操作时,它会被阻塞,直到操作完成。
- 阻塞操作通常会导致 CPU 的浪费,因为线程在等待 I/O 时并没有进行其他有用的工作。
- 一个连接一个线程:
- 每个客户端请求都会创建一个新的线程,每个线程对应一个 I/O 操作。
- 当并发连接数很多时,系统可能会因为线程数过多而导致性能瓶颈。
- 适用于连接数较少的场景:BIO 更适用于连接数较少、请求不频繁的应用场景,如一些小型应用或传统的阻塞式通信。
- 容易实现:相对于其他 I/O 模型(如 NIO 和 AIO),BIO 的实现比较简单,应用开发人员只需要关心 I/O 操作,不需要处理复杂的事件驱动机制。
BIO 的缺点:
- 线程资源浪费:每个连接都会对应一个独立的线程,当有大量并发连接时,会导致系统开销巨大,因为操作系统会为每个线程分配资源(如内存、栈空间等)。如果并发请求量很大,线程上下文切换开销也会非常高。
- 不适合高并发:BIO 模型非常依赖操作系统线程,线程数过多时容易造成系统性能下降。特别是在高并发的情况下,线程的创建和销毁频繁,容易耗尽系统资源。
- 效率低:在 I/O 操作过程中,线程被阻塞,无法处理其他请求,导致 CPU 的浪费。即使没有数据可读或可写,线程依然会等待,直到 I/O 完成。
1.2 IO流概述
IO流是基于流的概念,它将数据的输入和输出看作是一个连续的流。数据从一个地方流向另一个地方,流的方向可以是输入(读取数据)或输出(写入数据)。
IO流的原理是通过流的管道将数据从源头传输到目标地。源头可以是文件、网络连接、内存等,而目标地可以是文件、数据库、网络等。IO流提供了一组丰富的类和方法来实现不同类型的输入和输出操作。
IO流主要用于处理输入和输出操作,适用于以下场景:
- 文件读写:通过IO流可以读取和写入文件中的数据,如读取配置文件、写入日志等。
- 网络通信:通过IO流可以进行网络数据的传输和接收,如Socket通信、HTTP请求等。
- 数据库操作:通过IO流可以将数据读取到内存中,或将内存中的数据写入到数据库中。
- 文本处理:通过IO流可以读取和写入文本文件,进行文本处理和操作。
1.2.1 IO流分类
Java中的IO流可以按照数据的类型和流的方向进行分类:
- 按数据类型分类
- 字节流(Byte Stream):以字节为单位读写数据,适用于处理二进制数据,如图像、音频、视频等。常见的字节流类有InputStream和OutputStream。
- 字符流(Character Stream):以字符为单位读写数据,适用于处理文本数据。字符流会自动进行字符编码和解码,可以处理多国语言字符。常见的字符流类有Reader和Writer。
- 按流的方向分类
- 输入流(Input Stream):用于读取数据。输入流从数据源读取数据,如文件、网络连接等。常见的输入流类有FileInputStream、ByteArrayInputStream、SocketInputStream等。
- 输出流(Output Stream):用于写入数据。输出流将数据写入到目标地,如文件、数据库、网络等。常见的输出流类有FileOutputStream、ByteArrayOutputStream、SocketOutputStream等。
1.2.1.1 字符流
- 只用来处理文本数据 ;
- 数据最常见的表现形式是文件,字符流用来操作文件的子类一般是 FileReader 和 FileWriter 。
字符流读写文件注意事项:
- 写入文件必须要用 flush() 刷新 ;
- 用完流记得要关闭流 ;
- 使用流对象要抛出IO异常 ;
- 定义文件路径时,可以用"/"或者"\" ;
- 在创建一个文件时,如果目录下有同名文件将被覆盖 ;
- 在读取文件时,必须保证该文件已存在,否则抛出异常 ;
- 字符流的缓冲区 ;
- 缓冲区的出现是为了提高流的操作效率而出现的 ;
- 需要被提高效率的流作为参数传递给缓冲区的构造函数 ;
- 在缓冲区中封装了一个数组,存入数据后一次取出 。
1.2.1.2 字节流
- 用来处理媒体数据 。
字节流读写文件注意事项:
- 字节流和字符流的基本操作是相同的,但是想要操作媒体流就需要用到字节流 ;
- 字节流因为操作的是字节,所以可以用来操作媒体文件(媒体文件也是以字节存储的);
- 输入流(InputStream)、输出流(OutputStream);
- 字节流操作可以不用刷新流操作 ;
- InputStream特有方法:int available()(返回文件中的字节数);
- 字节流的缓冲区 ;
- 字节流缓冲区跟字符流缓冲区一样,也是为了提高效率 。
1.2.2 常用IO流
1.2.2.1 字节输入流类
- InputStream:用于从输入源读取字节数据的抽象类。
- FileInputStream:从文件中读取字节数据的类。
- ByteArrayInputStream:从字节数组中读取字节数据的类。
- BufferedInputStream:提供缓冲功能的字节输入流类。
- DataInputStream:读取基本数据类型的字节输入流类。
try (InputStream is = new FileInputStream("input.txt");BufferedInputStream bis = new BufferedInputStream(is)) {int data;while ((data = bis.read()) != -1) {System.out.print((char) data);}
} catch (IOException e) {e.printStackTrace();
}
1.2.2.2 字符输入流类
- Reader:用于从输入源读取字符数据的抽象类。
- FileReader:从文件中读取字符数据的类。
- BufferedReader:提供缓冲功能的字符输入流类。
- InputStreamReader:将字节流转换为字符流的类。
try (Reader reader = new FileReader("input.txt");BufferedReader br = new BufferedReader(reader)) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}
} catch (IOException e) {e.printStackTrace();
}
1.2.2.3 字节输出流类
- OutputStream:用于向输出目标写入字节数据的抽象类。
- FileOutputStream:将字节数据写入文件的类。
- ByteArrayOutputStream:将字节数据写入字节数组的类。
- BufferedOutputStream:提供缓冲功能的字节输出流类。
- DataOutputStream:将基本数据类型写入输出流的类。
try (OutputStream os = new FileOutputStream("output.txt");BufferedOutputStream bos = new BufferedOutputStream(os)) {String data = "Hello, World!";bos.write(data.getBytes());
} catch (IOException e) {e.printStackTrace();
}
1.2.2.4 字符输出流类
- Writer:用于向输出目标写入字符数据的抽象类。
- FileWriter:将字符数据写入文件的类。
- BufferedWriter:提供缓冲功能的字符输出流类。
- OutputStreamWriter:将字节流转换为字符流的类。
try (Writer writer = new FileWriter("output.txt");BufferedWriter bw = new BufferedWriter(writer)) {String data = "Hello, World!";bw.write(data);
} catch (IOException e) {e.printStackTrace();
}
1.2.3 Java Scanner类
Java 5添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序。
- 关于 nextInt()、next()、nextLine() 的理解 :
- nextInt() :只能读取数值,若是格式不对,会抛出 java.util.InputMismatchException 异常 ;
- next() :遇见第一个有效字符(非空格,非换行符)时,开始扫描,当遇见第一个分隔符或结束符(空格或换行符)时,结束扫描,获取扫描到的内容 ;
- nextLine() :可以扫描到一行内容并作为字符串而被捕获到 。
- 关于 hasNext()、hasNextLine()、hasNextxxx() 的理解 :就是为了判断输入行中是否还存在xxx的意思。
- 与 delimiter() 有关的方法的理解 :应该是输入内容的分隔符设置,
二、BIO工作机制
客户端:
- 通过Socket对象请求与服务端建立连接。
- 从Socket中得到字节输入或者字节输出流进行数据读写操作。
服务端:
- 通过ServerSocket注册端口。
- 服务端通过调用accept方法用于监听客户端的Socket请求。
- 从Socket中得到字节输入或者字节输出流进行数据读写操作。
三、简单编码实现
3.1 服务端
public class BioServer {public static void main(String[] args) {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(8080);System.out.println("Server is listening on port 8080...");while (true) {// 阻塞等待客户端连接Socket clientSocket = serverSocket.accept();System.out.println("Client connected: " + clientSocket.getInetAddress());// 为每个客户端请求创建一个新线程进行处理new Thread(new ClientHandler(clientSocket)).start();}} catch (IOException e) {e.printStackTrace();} finally {try {if(serverSocket != null){serverSocket.close();}} catch (IOException e){e.printStackTrace();}}}
}class ClientHandler implements Runnable {private Socket socket;public ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {BufferedInputStream bufferedInputStream = null;BufferedOutputStream bufferedOutputStream = null;try {bufferedInputStream = new BufferedInputStream(socket.getInputStream());;bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());System.out.println("收到来自客户端的消息:");byte[] bytes = new byte[1024]; //创建字节数组,存储临时读取的数据int len ; //记录数据读取的长度if ((len = bufferedInputStream.read(bytes)) > -1) { //长度为-1则读取完毕String result = new String(bytes,0,len);System.out.println(result);}String outString = "服务端收到,这里是线程" + Thread.currentThread().getName();System.out.println("回复信息给客户端: " + outString);bufferedOutputStream.write(outString.getBytes());bufferedOutputStream.flush();System.out.println("回复完成========");} catch (IOException e) {e.printStackTrace();} finally {System.out.println("关闭数据流========");try {if (bufferedInputStream != null) {bufferedInputStream.close();}if (bufferedOutputStream != null) {bufferedOutputStream.close();}} catch (IOException e){e.printStackTrace();}}}
}
工作过程:
- 服务器通过 ServerSocket 对象监听 8080 端口,等待客户端连接。
- 每当有一个客户端连接到服务器时,serverSocket.accept() 会阻塞当前线程,直到有客户端连接进来。
- 然后,服务器会为每个客户端连接创建一个新线程来处理该客户端的请求。
- 线程通过 BufferedInputStream 读取客户端发送的数据,并通过 BufferedOutputStream 回复客户端。
3.2 客户端
public class BioClient {public static void start() throws IOException {Socket socket = new Socket("127.0.0.1", 8080);String msg = "Hi,This is the BioClient";byte[] msgBytes = msg.getBytes();//1.拿到输出流//2.对输出流进行处理BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());//3.输出msgbufferedOutputStream.write(msgBytes);bufferedOutputStream.flush();System.out.println("客户端发送消息完毕: " + msg);System.out.println("客户端开始接收到消息==========");//4.对输入流进行处理BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());System.out.println("客户端接收到的消息:");byte[] inBytes = new byte[1024];int len;//5.读取输入流if ((len = bufferedInputStream.read(inBytes)) != -1) {String result = new String(inBytes, 0, len);System.out.println(result);}//6.关闭输入输出流bufferedOutputStream.close();bufferedInputStream.close();socket.close();}public static void main(String[] args) throws IOException {start();}
}
工作过程:
- 与服务端建立连接
- 发送消息给服务端
- 接收服务端返回的消息
相关文章:

Java BIO详解
一、简介 1.1 BIO概述 BIO(Blocking I/O),即同步阻塞IO(传统IO)。 BIO 全称是 Blocking IO,同步阻塞式IO,是JDK1.4之前的传统IO模型,就是传统的 java.io 包下面的代码实现。 服务…...

统计满足条件的4位数(信息学奥赛一本通-1077)
【题目描述】 给定若干个四位数,求出其中满足以下条件的数的个数:个位数上的数字减去千位数上的数字,再减去百位数上的数字,再减去十位数上的数字的结果大于零。 【输入】 输入为两行,第一行为四位数的个数n࿰…...

北京门头沟区房屋轮廓shp的arcgis数据建筑物轮廓无偏移坐标测评
在IT行业中,地理信息系统(GIS)是用于处理、分析和展示地理空间数据的重要工具,而ArcGIS则是GIS领域中的一款知名软件。本文将详细解析标题和描述中提及的知识点,并结合“门头沟区建筑物数据”这一标签,深入…...

Spring 面试题【每日20道】【其三】
1、Spring 中的 Profile 注解的作用是什么? 中等 Profile 注解在Spring框架中用于根据不同的环境配置文件(profiles)来激活或忽略某些Bean的注册。它允许开发者定义逻辑以区分不同环境下的bean定义,例如开发、测试和生产环境。 …...

FFmpeg(7.1版本)在Ubuntu18.04上的编译
一、从官网上下载FFmpeg源码 官网地址:Download FFmpeg 点击Download Source Code 下载源码到本地电脑上 二、解压包 tar -xvf ffmpeg-7.1.tar.xz 三、配置configure 1.准备工作 安装编译支持的软件 ① sudo apt-get install nasm //常用的汇编器,用于编译某些需要汇编…...

Apache Hudi数据湖技术应用在网络打车系统中的系统架构设计、软硬件配置、软件技术栈、具体实现流程和关键代码
网络打车系统利用Hudi数据湖技术成功地解决了其大规模数据处理和分析的难题,提高了数据处理效率和准确性,为公司的业务发展提供了有力的支持。 Apache Hudi数据湖技术的一个典型应用案例是网络打车系统的数据处理场景,具体如下: 大…...

安全策略配置
需求: 1、VLAN 2属于办公区;VLAN 3属于生产区 2、办公区PC在工作日时间(周一至周五,早8到晚6)可以正常访问0A Server,其他时间不允许 3、办公区PC可以在任意时刻访问web server 4、生产区PC可以在任意时刻访问0A Server,但是不能访问Web serv…...

c++ stl 遍历算法和查找算法
概述: 算法主要由头文件<algorithm> <functional> <numeric> 提供 <algorithm> 是所有 STL 头文件中最大的一个,提供了超过 90 个支持各种各样算法的函数,包括排序、合并、搜索、去重、分解、遍历、数值交换、拷贝和…...

【Envi遥感图像处理】008:波段(批量)分离与波段合成
文章目录 一、波段分离提取1. 提取单个波段2. 批量提取单个波段二、波段合成相关阅读:【ArcGIS微课1000例】0058:波段合成(CompositeBands)工具的使用 一、波段分离提取 1. 提取单个波段...

线程创建与管理 - 创建线程、线程同步(C++)
前言 在现代软件开发中,线程的创建和管理是并发编程的核心内容之一。通过合理地创建和管理线程,可以有效提高程序的响应速度和资源利用率。本文将详细讲解如何在C中创建线程,并探讨几种常见的线程同步机制。我们假设读者具备一定的C基础&…...

【C语言篇】“三子棋”
一、游戏介绍 三子棋,英文名为 Tic - Tac - Toe,是一款简单而经典的棋类游戏。游戏在一个 33 的棋盘上进行,两名玩家轮流在棋盘的空位上放置自己的棋子(通常用 * 和 # 表示),率先在横、竖或斜方向上连成三个…...

安培定律应用于 BH 曲线上的工作点
在本篇博文中,我将展示如何应用安培定律来确定磁芯包裹的导体必须承载多少电流才能从 BH 值工作点获得 B 值,该工作点对应于磁芯材料中的最大 B 值。我在 BH 曲线上使用两个工作点,一个在线性区域,另一个在饱和区域。 安培定律 H…...

深度求索DeepSeek横空出世
真正的强者从来不是无所不能,而是尽我所能。多少有关输赢胜负的缠斗,都是直面本心的搏击。所有令人骄傲振奋的突破和成就,看似云淡风轻寥寥数语,背后都是数不尽的焚膏继晷、汗流浃背。每一次何去何从的困惑,都可能通向…...

【CSS】什么是响应式设计?响应式设计的基本原理,怎么做
在当今多设备、多屏幕尺寸的时代,网页设计面临着前所未有的挑战。传统的固定布局已无法满足用户在不同设备上浏览网页的需求,响应式设计(Responsive Web Design)应运而生,成为网页设计的趋势和标准。本文将深入探讨响应…...

后盾人JS--继承
继承是原型的继承 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </hea…...

提升开发效率:IDE使用技巧与插件推荐
在软件开发过程中,选择一个合适的集成开发环境(IDE)并掌握其使用技巧,可以显著提高开发效率。本文将分享一些常用的IDE使用技巧,并推荐几款实用的插件,帮助开发者更好地利用IDE进行开发。 一、IDE使用技巧…...

开源模型应用落地-DeepSeek-R1-Distill-Qwen-7B与vllm实现推理加速的正确姿势(一)
一、前言 在当今人工智能技术迅猛发展的时代,各类人工智能模型如雨后春笋般不断涌现,其性能的优劣直接影响着应用的广度与深度。从自然语言处理到计算机视觉,从智能安防到医疗诊断,AI 模型广泛应用于各个领域,人们对其准确性、稳定性和高效性的期望也与日俱增。 在此背景下…...

小书包:让阅读更美的二次开发之作
小书包是在一款知名阅读软件的基础上进行二次开发的产品。在保留原有软件的基本功能和用户体验的同时,对其界面和视觉效果进行了精心美化,让阅读体验更加舒适和愉悦。 内置了171条书源,虽然数量不算多,但都是作者精挑细选出来的&a…...

MySQL 插入数据指南
MySQL 插入数据指南 引言 MySQL 是一款广泛使用的开源关系数据库管理系统,被广泛应用于各种规模的组织中。在数据库管理中,数据的插入是基础操作之一。本文将详细介绍如何在 MySQL 中插入数据,包括插入单条记录和多条记录,以及一…...

防火墙安全策略实验
一、拓扑图 需求 Cloud云: 二、防火墙配置 初始化防火墙 Username:admin Password:***** The password needs to be changed. Change now? [Y/N]: y Please enter old password: Admin123 Please enter new password: admin123 Please confirm new password: …...

【Redis】主从模式,哨兵,集群
主从复制 单点问题: 在分布式系统中,如果某个服务器程序,只有一个节点(也就是一个物理服务器)来部署这个服务器程序的话,那么可能会出现以下问题: 1.可用性问题:如果这个机器挂了…...

互联网行业常用12个数据分析指标和八大模型
本文目录 前言 一、互联网线上业务数据分析的12个指标 1. 用户数据(4个) (1) 存量(DAU/MAU) (2) 新增用户 (3) 健康程度(留存率) (4) 渠道来源 2. 用户行为数据(4个) (1) 次数/频率…...

多模块协同信息安全管理平台
1.产品介绍 产品名称 【SecureMOS - 多模块协同信息安全管理平台】 主要功能: [功能1] 模块化架构设计与集成 具体作用与使用方式: 通过模块化的设计,将信息安全系统分解为多个独立且可扩展的组件,便于快速部署和维护。需求满足与问题解…...

基于RK3588/RK3576+MCU STM32+AI的储能电站电池簇管理系统设计与实现
伴随近年来新型储能技术的高质量规模化发展,储能电站作为新能源领域的重要载体, 旨在配合逐步迈进智能电网时代,满足电力系统能源结构与分布的创新升级,给予相应规模 电池管理系统的设计与实现以新的挑战。同时,电子系…...

使用LightGlue进行图像配准并提取图像重叠区域
发表日期:2023年6月23日 项目地址:https://github.com/cvg/LightGlue https://github.com/cvg/glue-factory/ LightGlue是一个在精度上媲美Superglue,但在速度上比Superglue快一倍的模型。通过博主实测,LightGlue的配准效果比Su…...

DeepSeek-R1:开源机器人智能控制系统的革命性突破
目录 引言 一、DeepSeek-R1 的概述 1.1 什么是 DeepSeek-R1? 1.2 DeepSeek-R1 的定位 二、DeepSeek-R1 的核心特性 2.1 实时控制能力 2.2 多传感器融合 2.3 路径规划与导航 2.4 人工智能集成 2.5 开源与模块化设计 2.6 跨平台支持 三、DeepSeek-R1 的技术…...

第二十二章 MySQL锁之全局锁
目录 一、锁概述 二、全局锁概念 三、全局锁使用 四、全局锁特点 五、不加锁一致性数据备份 5.1. 实现方式 5.2. 优点和缺点 一、锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O&#x…...

pytorch实现简单的情感分析算法
人工智能例子汇总:AI常见的算法和例子-CSDN博客 在PyTorch中实现中文情感分析算法通常涉及以下几个步骤:数据预处理、模型定义、训练和评估。下面是一个简单的实现示例,使用LSTM模型进行中文情感分析。 1. 数据预处理 首先,我…...

Win11关闭登录密码?
或者使用winR快捷键, 输入: netplwiz 进入页面后,按照提示按ctrlaltdel键更改密码。 在跳转页面点击更改密码。 输入原密码后,将新密码设置为空即可。 Win11的两个实用技巧系列之如何关闭登录密码?_win11关闭密码还是要输入-CSDN博客...

e2studio开发RA4M2(6)----GPIO外部中断(IRQ)配置
e2studio开发RA4M2.6--GPIO外部中断(IRQ)配置 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置SWD调试口设置GPIO口配置按键中断配置中断回调函数主程序 概述 GPIO(通用输入/输出&a…...