13 IO流:字节流、字符流、缓冲流、文件复制(字节/字符/缓冲区)、字符转换流、打印流、IO框架(黑马Java视频笔记)

文章目录
- IO流 >> 读写数据的方案
- 1. 认识IO流
- 1)IO流的分类
- 2)IO流的体系
- 2. 文件字节输入流
- 2.1 创建文件字节流对象
- 2.2 读取文件
- 1)使用`read()`方法一个一个字节的读取
- 2)使用字节数组读取数据:`byte[]`
- 3)使用字节流读取中文,如何保证输出不乱码,怎么解决?
- 3. 文件字节输出流
- 3.1 创建输出流
- 3.2 使用write()写数据
- 4. 输入流和输出流用完后都要关掉流
- 5. 文件复制 -- 字节流
- 资源释放方案:
- 1)`try - catch - finally`
- 2)`try - with - resource`
- 6. 字符流FileReader - FileWriter
- 6.1 字符输入流FileReader
- 1)认识
- 2)FileReader读取步骤
- 6.2 字符输出流FileWriter
- 1)认识
- 2)write()方法写数据
- 7. 缓冲流
- 7.1 缓冲字节流
- 7.2 缓冲字符流
- 7.3 缓冲区vs不使用缓冲区
- 8. 其他流
- 8.1 字符输入转换流InputStreamReader:字节流->字符流
- 8.2 打印流:PrintStream 、PrintWriter
- 8.3 特殊数据流:DataInputStream/DataOutputStream -> 网络通信收发数据
- 9. IO框架
- 9.1 框架:
- 9.2 基本使用
IO流 >> 读写数据的方案
- 用于数据的读写(文件中的数据、网络中的数据…)
1. 认识IO流
I:Input,输入流,负责把数据读到内存中去O:Output,输出流,负责写数据
1)IO流的分类

2)IO流的体系
- 字节输入流
InputStream(读字节数据) - 字节输出流
Output Stream(写字节数据) - 字符输入流
Reader(读字符数据) - 字符输出流
Writer(写字符数据)

2. 文件字节输入流
💡以内存为基准,把磁盘文件中的数据以字节的形式读入到内存中去

2.1 创建文件字节流对象
File file = new File("F:/Users/Typora/input.txt");
InputStream ffis = null;
InputStream fis = null;try {// 方式一:ffis = new FileInputStream(file);// 方式二:fis = new FileInputStream("F:/Users/Typora/input.txt");
} catch (FileNotFoundException e) {e.printStackTrace();
}
🤔在try-catch中创建文件字节流对象,其变量为局部变量,外部不可用的 >>> 先在try-catch外创建空的字节流对象,然后在try-catch中复制
2.2 读取文件
1)使用read()方法一个一个字节的读取
// 2、使用FileInputStream字节输入流管道中的read方法读取文件字节数组到内存中
// 定义一个变量记住每次读取的一个字节
int b;
while ((b = fis.read()) != -1) {System.out.print((char) b);
}
⚠️一次只读取一个字节,对于纯英文合适,有多字节字符就不合适了

2)使用字节数组读取数据:byte[]
// 定义一个字节数组,用来装读取到的字节数组。
// 重新创建一个文件字节输入流管道与源文件接通:上面字节读取的已经读完了
fis = new FileInputStream("F:/Users/Typora/input.txt"); byte[] buffer = new byte[1024];
// 定义一个变量记录每次读取到的字节数组长度。
int len;
while((len = fis.read(buffer))!=-1){System.out.println(new String(buffer,0,len)); // 把字节数组按照一定的编码格式,按照一定的格式,输出到控制台,默认UTF-8
}

💡当数组的容量很小时,可能因只读取了一个多字节字符的一部分,从而导致解码后出现乱码

3)使用字节流读取中文,如何保证输出不乱码,怎么解决?
-
小文件:一次读完全部字节
readAllBytes[]
-
如果文件过大,创建的字节数组也会过大,可能引起内存溢出
💡读取文本适合用字符流,字节流适合做数据的转移,比如文件赋值

3. 文件字节输出流
- 以字节为基准,把内存中的数据以字节的形式写出到文件中去

3.1 创建输出流
// 1、创建FileOutputStream对象,指定写入的目的地
OutputStream fos = null;
try {fos = new FileOutputStream("F:/Users/Typora/output.txt"); // true表示追加内容,false表示覆盖内容// fos = new FileOutputStream("F:/Users/Typora/output.txt" , true); // true表示追加内容,false表示覆盖内容
} catch (FileNotFoundException e) {e.printStackTrace();
}
3.2 使用write()写数据
//2、使用FileOutputStream对象中的方法write,把数据写入到目的地中
fos.write('a');
fos.write(65);
fos.write('\n'); // 换行
// 写一个字符串
byte[] bytes = "我爱你中国666".getBytes(StandardCharsets.UTF_8); // getBytes()获取编码, 使用UTF-8编码
fos.write(bytes);
fos.write('\n'); // 换行
// 写字符串的部分
fos.write(bytes, 0, 3);//刷新
fos.flush();

4. 输入流和输出流用完后都要关掉流
💡使用try-catch-finally资源释放方案会自动关闭流,释放资源
fis.close();
fos.close();
5. 文件复制 – 字节流

public static void main(String[] args) {// 目标:使用字节流完成文件的复制操作// 源文件:F:/Users/Typora/input.txt// 目标文件:F:/Users/Typora/output.txt(目标文件要带上文件名,无法自动生成文件名)String srcPath = "F:/Users/Typora/input.txt";String destPath = "F:/Users/Typora/output.txt";copyFile(srcPath, destPath);
}// 复制文件
public static void copyFile(String srcPath, String destPath) {// 1、创建一个文件字节输入流管道与源文件接通,一个文件字节输出流管道与目标文件接通try (InputStream fis = new FileInputStream(srcPath);FileOutputStream fos = new FileOutputStream(destPath);) {// 2、读取一个字节数组,写入一个字节数组,循环读取,循环写入byte[] buffer = new byte[1024];int len;while ((len = fis.read(buffer)) != -1) {fos.write(buffer, 0, len); // 写入一个字节数组,从数组的哪个索引开始读,读几个字节}} catch (Exception e) {e.printStackTrace();}System.out.println("复制完成!");
}
资源释放方案:
1)try - catch - finally
try{}catch(Exception e){e.printStackTrace();
}finally{}
finally代码区:无论try中的程序是否正常执行,最后都会执行finally区,除非JVM终止。
💡一般用于程序执行完成后进行资源的释放操作 >>> 但是有点臃肿,每一个流都要手写代码关闭
2)try - with - resource
try(定义资源1;定义资源2;....){可能出现异常的代码;
}catch(异常类名 变量名){异常的处理代码;
}
💡资源使用完毕后,会自动调用其close() 方法,完成对资源的释放!
- try()中只能放置资源,否则报错
- 资源一般是指最终实现了AutoCloseable接口

6. 字符流FileReader - FileWriter
6.1 字符输入流FileReader
1)认识
- 以内存为基准,把文件中的数据以
字符的形式读入到内存中

2)FileReader读取步骤
① 创建字符输入流 char[]
② 通过read方法获取文件内容
public static void main(String[] args) {// 目标:掌握文件字符输入流读取字符内容到程序中来// 1、创建文件字符输入流管道与源文件接通try (Reader fr = new FileReader("F:/Users/Typora/input.txt");) {// 2、定义一个字符数组,用于装读取到的字符内容char[] buffer = new char[3];int len; // 记录每次读取到的字符数组长度while ((len = fr.read(buffer)) != -1) {// 3、把字符数组中的内容按照一定的编码格式,按照一定的格式,输出到控制台String str = new String(buffer, 0, len);System.out.print(str);}// 扩展:文件字符输入流每次读取多个字符,减少系统调用,性能较好,而且读取中文是按照字符读取,不会出现乱码! ---- 一种读取中文很好的方案} catch (Exception e) {e.printStackTrace();}

6.2 字符输出流FileWriter
1)认识
- 以内存为基准,把内存中的数据以
字符的形式写出到文件中去

2)write()方法写数据
public static void main(String[] args) {// 目标:搞清楚文件字符输出流的使用try(// 1、创建FileWriter对象,指定写入的目的地FileWriter fw = new FileWriter("F:/Users/Typora/output.txt");){// 2、写一个字符出去fw.write(65); // 65是ASCII码,Afw.write("\r\n");// 3、写一个字符串出去fw.write("java");fw.write("\r\n");// 写字符串的一部分fw.write("Hello", 1, 2);fw.write("\r\n");// 4、写一个字符数组出去char[] chars = {'a', 'b', 'c'};fw.write(chars);fw.write("\r\n");// 5、写一个字符数组的一部分出去fw.write(chars, 1, 2);fw.write("\r\n");// fw.flush(); // 刷新缓冲区,将数据写入到目的地中// 刷新后,流可以继续使用fw.close(); // 关闭流,关闭包含了刷新!关闭后流不再可用!}catch (Exception e){e.printStackTrace();}}

⚠️ 刷新数据:fw.flush()
7. 缓冲流

7.1 缓冲字节流
💡提高字节输入流读取数据的性能


- 文件复制
public static void main(String[] args) {// 目标:了解缓冲字节流的使用String srcPath = "F:/Users/Typora/input.txt";String destPath = "F:/Users/Typora/output.txt";copyFile(srcPath, destPath);}public static void copyFile(String srcPath, String destPath) {//1、创建一个文件字节输入流管道与源文件接通,一个文件字节输出流管道与目标文件接通try (// 这里只能放置资源对象,用完后,最终会自动调用close()方法关闭资源InputStream fis = new FileInputStream(srcPath);// 把低级的字节输入流转换成高级的缓冲字节输入流InputStream bis = new BufferedInputStream(fis); // 多态FileOutputStream fos = new FileOutputStream(destPath);// 把低级的字节输出流转换成高级的缓冲字节输出流OutputStream bos = new BufferedOutputStream(fos);) {// 2、读取一个字节数组,写入一个字节数组,循环读取,循环写入byte[] buffer = new byte[1024];int len;while ((len = bis.read(buffer)) != -1) {bos.write(buffer, 0, len); // 写入一个字节数组,从数组的哪个索引开始读,读几个字节}System.out.println("复制完成!");}catch(Exception e){e.printStackTrace();}
}
7.2 缓冲字符流



public static void main(String[] args) {// 目标:缓冲字符输入流/缓冲字符输出流try(Reader fr = new FileReader("F:/Users/Typora/input.txt");Writer fw = new FileWriter("F:/Users/Typora/output.txt");// readLine是BufferedReader新增的,不用Reader多态创建BufferedReader br = new BufferedReader(fr);BufferedWriter bw = new BufferedWriter(fw);){String line;while ((line = br.readLine()) != null){System.out.println(line);bw.write(line); // 写入bw.newLine(); // 换行}}catch (Exception e){e.printStackTrace();}
}
7.3 缓冲区vs不使用缓冲区

缓冲区的 read() 方法:
- 先获取一整块数据到缓冲池,然后在从缓冲池里一个一个字节获取,或者一个一个字节数组获取
不使用缓冲区:
- 每次都是从磁盘中获取
8. 其他流
8.1 字符输入转换流InputStreamReader:字节流->字符流
- 解决不同编码时,字符流读取文本内容乱码的问题
解决思路:
① 获取文件的原始字节流
② 再将其按真实的字符集编码转成字符输入流
③ 这样字符输入流中的字符就不乱码了

public static void main(String[] args) {// 目标:认识字符输入转换流InputStreamReader的用法try(// 先提取文件的原始字节流InputStream is = new FileInputStream("F:\\Study\\Java\\javaseprojectmax\\day03-file-io\\src\\com\\study\\intput");// 再把字节输入流转换为字符输入流Reader isr = new InputStreamReader(is, StandardCharsets.UTF_8);// 再把字符输入流转换为字符缓冲输入流BufferedReader br = new BufferedReader(isr);){String line;while((line = br.readLine())!= null){System.out.println(line);}}catch(Exception e){}
}
8.2 打印流:PrintStream 、PrintWriter
- 可以实现更方便、更高效的打印数据出去 >>> 写数据
使用字节输出流/字符输出流时,会将数字字符转成对应ASCII码的英文字符


8.3 特殊数据流:DataInputStream/DataOutputStream -> 网络通信收发数据
DataOutputStream:
- 允许把数据和其类型一并写出去

public static void main(String[] args) {try(DataOutputStream dos = new DataOutputStream(new FileOutputStream("f:/Users/Typora/output.txt"));){dos.writeBoolean(true);dos.writeByte(127);dos.writeChar('a');dos.writeShort(32767);dos.writeInt(2147483647);dos.writeDouble(3.1415926);}catch(Exception e){e.printStackTrace();}
}
public static void main(String[] args) {try(DataInputStream dis = new DataInputStream(new FileInputStream("f:/Users/Typora/output.txt"));){System.out.println(dis.readBoolean());System.out.println(dis.readByte());System.out.println(dis.readChar());System.out.println(dis.readShort());System.out.println(dis.readInt());System.out.println(dis.readDouble());}catch(Exception e){e.printStackTrace();}
}
💡DataOutputStream对象使用write方法写数据时,也包含其类型,在文本上是乱码,在读取时通过DataInputStream读取数据即可以还原数据

9. IO框架
9.1 框架:
- 一个预先写好的代码库或一组工具,旨在简化和加速开发过程
- 形式:
- 一般是把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去
IO框架: 下载链接
- 封装了Java提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等


9.2 基本使用

File srcFile = new File("F:/Users/Typora/input.txt");
File destFile = new File("F:/Users/Typora/copy.txt");
FileUtils.copyFile(srcFile, destFile); // 复制文件,如果没有会新建文件
相关文章:
13 IO流:字节流、字符流、缓冲流、文件复制(字节/字符/缓冲区)、字符转换流、打印流、IO框架(黑马Java视频笔记)
文章目录 IO流 >> 读写数据的方案1. 认识IO流1)IO流的分类2)IO流的体系 2. 文件字节输入流2.1 创建文件字节流对象2.2 读取文件1)使用read()方法一个一个字节的读取2)使用字节数组读取数据:byte[]3)使用字节流读…...
深入理解 TypeScript 中的迭代器(Iterators)与生成器(Generators)
一、为什么需要迭代协议? 在现代 JavaScript/TypeScript 开发中,我们经常需要处理各种集合型数据:数组、Map、Set 甚至是自定义数据结构。ES6 引入的迭代协议(Iteration Protocols)正是为了解决统一遍历机制的问题。通…...
靶场(十四)---小白心得思路分享---Extplorer
启程: 开始扫描端口服务,发现什么都没有,果断进行下一步目录扫描 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 98:4e:5d:e1:e6:97:29:6f:…...
逆向中常见的加密算法识别
1、base64及换表 base64主要是将输入的每3字节(共24bit)按照每六比特分成一组,变成4个小于64的索引值,然后通过一个索引表得到4个可见的字符。 索引表为一个64字节的字符串,如果在代码中发现引用了这个索引表“ABCDEF…...
【初学者】怎样学习、使用与研究算法?
李升伟 整理 学习、使用与研究算法是一个系统化的过程,涉及理论学习、实践应用和深入研究。以下从学习方法、使用技巧和研究方向三个方面进行详细阐述: 一、学习方法 1. 分阶段学习 初级阶段:掌握经典算法,如最短路径算法&…...
【愚公系列】《高效使用DeepSeek》018-错题本整理
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
Linux上的`i2c-tools`工具集的编译构建和安装
源码复制到Ubuntu系统中并解压 的i2c-tools工具集的源码百度网盘下载链接: https://pan.baidu.com/s/1XNuMuT1auT1dMzYo3LAFmw?pwdi6xe 终端进入源码目录 cd /home/book/mybuild/i2c-tools-4.2执行编译构建命令 运行下面的命令进行编译构建 make CC${CROSS_COM…...
langgraph简单Demo(使用langserve实现外部调用)
前言 这个示例是研究如何使用langserve实现外部调用 接入大模型参考文章:接入阿里云百炼 1、安装依赖 pip install langserve fastapi uvicorn pip install sse_starlette 2、代码实现 from fastapi import FastAPI from langchain_core.messages import HumanM…...
【C#高阶编程】—单例模式详解
C# 单例模式 单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景,比如配置文件管理、日志记录、数据库连接池等。 单例模式的核心特点 私有构造函数:…...
折叠树报表
折叠树报表中包含了三种信息: 1.树组织信息-可展开、收拢 2.节点的统计信息(汇总求和) 3.每个节点对应的数据信息 一、准备数据 mysql8 数据库中存在两张表 org和store表。 org表和部分数据如下,其中orgname是组织的名称,codepath是完整的组织代码,seq是每个节点的顺序,可…...
Python个人学习笔记(16):模块(os)
四、os模块 主要用于文件夹处理 (一)文件夹相关 os.makedirs(‘dirname1/dirname2’) :创建文件夹目录,不能重复创建,用的多 代码: os.makedirs(a/b/c)结果: os.removedirs(‘dirname1’)&…...
虚拟地址空间(下)进程地址空间(上)
一.关于页表组成 1.权限(rwx) 作用:如1.让代码区变成只读的 2.写时拷贝的实现:子进程创建时其页表指向的父进程代码和数据权限都是只读的,子进程试图修改,触发错误,系统开始写时拷贝。 来源:…...
【数据集分享】青藏高原两次强震玛多地震和漾濞地震的震源过程
2021年5月21日,5小时内在青藏高原不同区域发生了漾濞6.4级和玛多7.4级强烈地震,表明印度板块和欧亚大陆板块的碰撞汇聚作用下青藏高原持续和频繁的 剧烈构造运动和地震活动。本研究利用地震记录和空间对地观测同震位移资料(InSAR)…...
jmeter环境搭建及使用
Meter 是一个开源的性能测试工具,用于测试静态和动态资源的性能。 1、安装 官网下载: 下载地址:Apache JMeter - Download Apache JMeter 网盘下载: 通过百度网盘分享的文件:apache-jmeter-5.6.3.rar 链接&#x…...
Python 鼠标轨迹算法 - 防止游戏检测
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
网络编程--服务器双客户端聊天
写一个服务器和客户端 运行服务器和2个客户端,实现聊天功能 客户端1和客户端2进行聊天,客户端1将聊天数据发送给服务器,服务器将聊天数据转发给客户端2 要求: 服务器使用 select 模型实现 ,客户端1使用 poll 模型实现…...
yum软件包乾坤大挪移(Yum Package Qiankun Great Migration)
yum软件包乾坤大挪移 背景 由于很多的生产环境是无法连接外网的,因此用yum或者dnf命令来安装软件包常常是一个比较麻烦的事情,原因是很多软件的依赖很复杂,如果要一个个下载、拷贝、再安装,这往往是一个非常繁琐冗杂的过程&…...
Java:读取中文,read方法
public static void main(String[] args) throws IOException {FileReader fr new FileReader("C:\\aaa\\a.txt");//字符流的底层也是一个字节一个字节读取的,遇到中文就一次读多个,GBK一次读两个,UTF-8一次读三个字节//idea默认U…...
[GHCTF 2025]真会布置栈吗?
题目是一个聊天室,我们先按照题目使用 /help Help: /help 显示此帮助信息 /msg [text] 在当前频道发送消息 /nick [name] 更改你的用户名 /list 列出可用的频道 /join [channel] 切换到不同的频道 /channel …...
集合的练习1-2
//练习1: import java.util.ArrayList;public class ArraylistTest1 {public static void main(String[] args){ArrayList<String> listnew ArrayList<>();//需求:定义一个集合,添加字符串,并进行遍历//遍历格式&…...
英语词性--数词
文章目录 数词概念数词分词基数词序数词 基数与序数词的区别基变序的规律 数词概念 数词(Numerals) 是英语中用于表示 数量(基数)或顺序(序数) 的词类,通常用于描述数字、计数、顺序等。 例如&…...
面试整理--一个报告生成的方案解析
最近又快到了年后找工作的时间,近期写点工作积累,供大家参考。 欢迎关注公主号【测试开发备忘录】,交流职场技巧和经验 首先从工作中一个报错来展开: Start directory is not importable: 错误信息 "Start directory is not importable…...
C#零基础入门篇(18. 文件操作指南)
## 一、文件操作基础 在C#中,文件操作主要通过System.IO命名空间中的类来实现,例如File、FileStream、FileInfo等。 ## 二、常用文件操作方法 ### (一)文件读取 1. **使用File.ReadAllText方法读取文件内容为字符串** …...
Linux 一步部署DHCP服务
#!/bin/bash #脚本作者和日期 #author: PEI #date: 20250319 #检查root权限 if [ "$USER" ! "root" ]; then echo "错误:非root用户,权限不足!" exit 0 fi #防火墙与高级权限 systemctl stop firewa…...
如何打造安全稳定的亚马逊采购测评自养号下单系统?
在当今的电商领域,亚马逊作为全球领先的在线购物平台,其商品种类繁多,用户基数庞大,成为了众多商家和消费者的首选。而对于一些需要进行商品测评或市场调研的用户来说,拥有一个稳定、安全的亚马逊账号体系显得尤为重要…...
【大模型学习】第二十四章 生成式人工智能(GAI)简介
目录 一、什么是生成式人工智能(GAI)? 二、核心技术原理 三、典型应用场景 四、技术特点与挑战 五、训练优化策略 六、关键性能指标(2025年基准) 七、技术演进方向: 一、什么是生成式…...
Pytorch中layernorm实现详解
平时我们在编写神经网络时,经常会用到layernorm这个函数来加快网络的收敛速度。那layernorm到底在哪个维度上进行归一化的呢? 一、问题描述 首先借用知乎上的一张图,原文写的也非常好,大家有空可以去阅读一下,链接放…...
YOLO11报错:AttributeError: module ‘torch‘ has no attribute ‘OutOfMemoryError‘
事情是这样的:前几天YOLO11的代码还是可以训练的,昨天训练了一天,今天换模型就报这个错。 AttributeError: module torch has no attribute OutOfMemoryError我查了一下:YOLO11官方代码issues里面也有人有同样的问题,…...
基于java的ssm+JSP+MYSQL的高校四六级报名管理系统(含LW+PPT+源码+系统演示视频+安装说明)
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...
Starrocks 命令 Alter table DISTRIBUTED 重分布数据的实现
背景 在前文Starrocks 写入报错 primary key memory usage exceeds the limit中,可以通过ALTER TABLE xxxx DISTRIBUTED BY HASH(xx) BUCKETS 50;来改变数据的分布状态,具体的执行过程是怎么样的呢? 分析 首先对应的g4文件中为 alterTableStatement &…...
