JAVA入门——IO流
一、了解File类
- 这个类里面提供了一些文件相关的方法,了解即可,方法有很多,不好背
- 下面这个是最常用的
- 只能对文件本身操作,不能读取数据
public File[] listFiles();//获取当前路径下的所有内容
注意:如果是需要权限才能访问的文件夹,那么会返回null
二、初识IO流以及四个基本流
- 为了解决数据的存储与读取问题
IO流的分类
按流的方向分:
- 输入流:文件→程序
- 输出流:程序→文件
按操作文件的类型分:
- 字节流:操作所有类型文件
- InputStream:字节输入流
- OutputStream:字节输出流
- 字符流:操作纯文本文件
- Reader:字符输入流
- Writer:字节输出流
- 上面四个都是顶层的抽象类
初识字节输出流:
- 1.创建字节输出流对象
- 参数是字符串表示的路径或者FIle对象都是可以的
- 如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
- 如果文件已经存在,会清空文件
- 2.写数据
- 传的是整数,实际上写到文件里是ASCII码对应的值
- 3.释放资源
- 结束资源的占用,不然其他人无法操作这个文件
public class Demo1 {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("src\\a.txt");fos.write(97);fos.close();}}
1.FileOutputStream写数据的三种方式:

- 例:
public class Demo1 {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("a.txt");byte[] arr = {97,98,99,100,101};//1.
// fos.write(arr);
// fos.close();//2.//参数:数组,起始索引,要写入的长度(个数)fos.write(arr,1,2);fos.close();}
}
2.写数据的两个问题:
- 换行:
- 注意不同操作系统换行符不同
public class Demo1 {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("a.txt");String str = "1145141919810";byte[] arr = str.getBytes();fos.write(arr);//换行符//windows:\r\n 回车换行//Linux:\n//Mac:\r//Java中进行了优化,我们写不全也能自动补全String wrap = "\r\n";byte[] arr2 = wrap.getBytes();fos.write(arr2);String str2 = "wsnd";byte[] arr3 = str2.getBytes();fos.write(arr3);fos.close();}
}
- 不删除原来数据:
- 在创建对象时,第二个参数传ture,表示打开续写开关,他默认是false
FileOutputStream fos = new FileOutputStream("a.txt",true);
初识字节输入流:
1.步骤:和字节输出流基本一致,一定注意要释放资源
public class Demo2 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");int b1 = fis.read();//会一个一个读取,如果读取不到,返回-1System.out.println((char)b1);}
}
2.细节:
- 创建对象:
- 如果文件不存在,就直接报错
- 读取数据:
- 一次读取一个字节,读出来的是数据对应的ASCII码值
- 读到文件末尾时,read方法返回-1
- 释放资源:
- 每次读取完毕,必须释放资源
- 先开的后关闭
3.FileInputStream循环读取:(拷贝练习)(这里不要写太大的文件,这个方法拷贝很慢)
public class Demo2 {public static void main(String[] args) throws IOException {//拷贝练习FileInputStream fis = new FileInputStream("D:\\My_study_resoure\\概率论\\1-3 随机事件的概率(1).pdf");FileOutputStream fos = new FileOutputStream("copy.pdf");int b;while((b = fis.read()) != -1){fos.write(b);}//规则:先开的最后关闭fos.close();fis.close();}
}
4.读取优化,一次读取多个数据:
- 每次读取会尽可能把数组装满
- 建议数组大小为1024的整数倍
- 返回值表示这次读取了多少个字节的数据
- 注意:每次读取到数组中,不会清除上一次的数据,如果读入的比上次读入的少,可能会多打印出来其他的值
public int read(byte[] buffer)
拷贝代码优化:
public class Demo2 {public static void main(String[] args) throws IOException {//拷贝练习FileInputStream fis = new FileInputStream("D:\\My_study_resoure\\概率论\\1-3 随机事件的概率(1).pdf");FileOutputStream fos = new FileOutputStream("copy.pdf");int len;byte[] bytes = new byte[1024 * 1024 * 5];while((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);//一定不能读取数组中的所有的数据}fos.close();fis.close();}
}
try..catch异常处理:
1.认识finally
finally{
//里面的代码一定被执行,除非虚拟机停止
//适合把资源释放写在这里面
}
public class Demo2 {public static void main(String[] args) {FileInputStream fis = null;FileOutputStream fos = null;try {//拷贝练习fis = new FileInputStream("D:\\My_study_resoure\\概率论\\1-3 随机事件的概率(1).pdf");fos = new FileOutputStream("copy.pdf");int len;byte[] bytes = new byte[1024 * 1024 * 5];while((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);//一定不能读取所有的数据}} catch (IOException e) {throw new RuntimeException(e);} finally {//这里还需要对fis fos进行非空判断if(fos != null) {try {fos.close();} catch (IOException e) {throw new RuntimeException(e);}}if(fis != null) {try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}
2.优化
- 可以看见,非常的繁琐,所以JDK7以后有了一些优化方案
- 可以自动释放资源,但是这个类必须实现了AutoColseable这个接口

字符集ASCII、GBK、Unicode:
- GBK:
- 一个汉字用两个字节去存储
- 高位二进制一定是以1开头,转成十进制后是负数
- 这是为了区分汉字与英文,英文是以0开头
- 完全兼容ASCII
- Unicode(字符集):
- UTF-8(编码方式):1~4个字节来存储
- 中文汉字3个字节
- 英文1个字节
- UTF-16:用2~4个字节存储
- UTF-32:固定用4个字节存储
- UTF-8(编码方式):1~4个字节来存储

为什么会有乱码?
- 1.读取数据时未读取完整的汉字
- 不要用字节流读取文本文件(一次只读一个字节,那么汉字三个字节就炸了)
- 但是拷贝可以,因为我们并不会在拷贝中途使用数据,每个字节都完整拷贝过来了。 (不存在数据丢失)
- 2.编码和解码的方式不统一
JAVA中编码、解码的方法:
- 注意:
- 指定方式里面小写,大写均可
- 不同编译器默认的编码方式可能不同,一定要注意


字符流:
1.特点:
- 底层其实就是字节流,在字节流的基础上添加了字符集的概念
- 输入流:一次读一个字节,遇到中文时,一次读多个字节
- 输出流:底层会把数据按照指定的编码方式进行编码,变成字节后再写到文件中
2.输入流学习——FileReader为例
- 1.创建对象
- 文件不存在,会报错

- 2.读取数据
- 一次读一个字节,遇到中文时,一次读多个字节,解码后返回一个整数
- 读到末尾返回 -1

- 3.释放资源/关流
例:
- 注意:read方法读取到的都是解码后转换成的十进制数据,我们要强制转换成char类型才能看见字符
public class Demo2 {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");int ch;while((ch = fr.read()) != -1) {System.out.print((char)ch);}fr.close();}
}
有参的read方法底层将读取数据、解码、强制类型转换三步合并了,把得到的字符放到了数组中,这个和无参的不一样!
3.输出流学习——FileWriter为例(书写细节和字节输出流那里一样)
1.构造方法:

2.成员方法:

4.字符输入流底层原理
1.创建字符流输入对象
- 底层:关联文件,并创建缓冲区(长度为8192的字节数组 1024 * 8)(bytebuffer)
2.读取数据
- 底层:
- 判断缓冲区中是否有数据可以读取
- 缓冲区中没有数据:从文件中获取数据,撞到缓冲区中,每次尽可能装满缓冲区
- 如果文件中也没有数据了,返回-1
- 缓冲区有数据:从缓冲区中读取
5.字符输出流底层原理
- 底层:
- 写数据时,会先写到缓冲区中(缓冲区大小也是8192个字节)
- 数据不会直接写到本地中,写到本地的方法:
- 缓冲区满后,会进行一次写出
- 调用flush()方法,可以进行一次写出
- 关流后,可以写出(注意关流后与文件的关联就断开了,不能再进行文件相关的操作了)
三、其他高级流
1.缓冲流
原理:
- 底层自带了8192的缓冲区来提高性能
- 只是进行了包装,底层实际上还是基本流
字节缓冲流的两个包装方法:
- BufferedInputStream(InputStream is);
- BufferedOutputStream(OutputStream os);
拷贝文件的例子:
- 注意:我们不用关闭基本流,因为缓冲流底层有关闭基本流的代码
public class Demo2 {public static void main(String[] args) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));int b;while ((b = bis.read()) != -1){bos.write(b);}bis.close();bos.close();}
}
提高效率的原理:
- 读取时,先尽量读满缓冲区,写时会往另一块缓冲区里写,这些都是在内存中的,减少了和磁盘之间的读写,所以更加的快
字符缓冲流:
- 大部分都和字节缓冲流一样,这里只介绍最常用的两个方法(很好用)
- 注意JAVA中char类型占两个字节,字符缓冲流底层是个char类型数组,所以是16kb
- public String readLine();//一次读取一行代码,如果没数据可读会返回null
- 遇到回车、换行会停止,但是不会读出来回车和换行,想要换行要手动加
- public void newLine();//跨平台的换行
- 不同的平台换行不同,用这个可以跨平台
2.转换流(字符流的一种)
作用:
- 转换字符流和字节流
- 指定字符集进行读写数据:(JDK11后淘汰)(因为可以在FileReader中指定编码格式了,所以之间创建FileReader的对象就行了,输出流也一样,在FileWriter中用即可)
- 字节流想用字符流中的方法(重要)
- 对象名:
- InputStreamReader
- OutputStreamReader
- 例:想一次读一行数据,并且不出现乱码
public class Demo2 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");//我们想一次读取一行,并且不出现乱码//所以要用转换流,变成字符流InputStreamReader isr = new InputStreamReader(fis);//参数中,只要是Reader就可以,所以我们传isrBufferedReader br = new BufferedReader(isr);String line;while((line = br.readLine()) != null) {System.out.println(line);}br.close();}
}
3.序列化流(对象操作输出流)
作用:
- 把Java中的对象写到本地文件
- 写到本地的文件长得很抽象,用反序列化流才能看懂
方法:
- ObjectOutputStream(OutputStream out);//把基本流包装成高级流
- public final void writeObject(Object obj);//把对象序列化写出到文件中去
细节:
- 直接输出对象,会报错NotSerializableException异常
- 解决方案:要让对应的类实现Serializable接口(这是个空接口,只用来作为标记作用)
例:
public class Demo2 {public static void main(String[] args) throws IOException {//1.创建对象Student stu = new Student("wangjunyang",114);//2.创建序列化流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"));//3.写出数据oos.writeObject(stu);oos.close();}
}
4.反序列化流(对象操作输入流)
方法:
- ObjectInputStream(InputStream is);
- Object readObject();//注意读到的是Object类型
细节:
- 当我们序列化一个类后,修改了JavaBean类,我们再去反序列化这个类会报错
- 原因:序列号不匹配
- 处理方案:固定序列号的值
- private static final long serialVersionUID = xxxx;//注意名字只能是这个
- 可以通过设置中搜索Serializable,勾选上JVM中的那个不带xxxUID的可序列化类和transient字段在反序列化时未初始化,这样就能在IDEA中提示你了,然后自动生成
- 如果我们不想某个属性被序列化呢?可以加上transient修饰
- 当我们要序列化多个对象时,我们一般放在集合中,然后去序列化这个集合,这样可以避免忘了对象有几个
例:
public class Demo2 {public static void main(String[] args) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"));Student o = (Student)ois.readObject();System.out.println(o);ois.close();}
}
5.打印流(只有输出流)
分类:
PrintStream
PrintWriter
特点:
- 只操作目的地文件,不操作数据源
- 特有的写出方法,可以实现数据的原样写出
- 特有的写出方法,可以实现自动刷新,自动换行
字节打印流:
注意:
- 字节流底层没有缓冲区,开不开自动刷新都一样

成员方法:
- 常规方法:
- write(int b)
- 特有方法:
- println() 打印任意数据,自动刷新,自动换行
- print() 打印任意数据,没有换行
- printf(String format,Object..args) 带有占位符,不换行
字符打印流:
- 底层多了缓冲区,自动刷新那个参数就有用了
- 其他的和上面的字节流基本一致
打印流应用:
- 其实System.out就是自动创建了一个打印流的对象,是一个特殊的打印流,称作系统的标准输出流
- 注意这个流是不能关闭的,在系统中是唯一的
public class Demo1 {public static void main(String[] args) throws IOException {PrintStream out = System.out;out.println("123");}
}
6.解压缩流(输入流)
- 压缩包里每一个文件都是ZIpEntry对象
- 解压本质就是把ZipEntry按照层级拷贝到本地
相关文章:
JAVA入门——IO流
一、了解File类 这个类里面提供了一些文件相关的方法,了解即可,方法有很多,不好背下面这个是最常用的只能对文件本身操作,不能读取数据 public File[] listFiles();//获取当前路径下的所有内容 注意:如果是需要权限才…...
Spring Boot 流式响应豆包大模型对话能力
当Spring Boot遇见豆包大模型:一场流式响应的"魔法吟唱"仪式 一、前言:关于流式响应的奇妙比喻 想象一下你正在火锅店点单,如果服务员必须等所有菜品都备齐才一次性端上来,你可能会饿得把菜单都啃了。而流式响应就像贴…...
Android Binder 用法详解
Binder 是 Android 系统中的一种进程间通信(IPC)机制,它允许不同进程之间进行高效通信。Binder 在 Android 系统中被广泛使用,例如在 Activity 与 Service 的交互中。 Binder 的基本组成 实现 Binder 通信通常包含以下几个关键部…...
在Ubuntu中,某个文件的右下角有一把锁的标志是什么意思?
在Ubuntu中,某个文件的右下角有一把锁的标志是什么意思? 在 Ubuntu(或其他基于 GNOME 文件管理器的 Linux 发行版)中,文件或文件夹的右下角出现一把“锁”标志,通常表示 你当前的用户没有该文件/文件夹的写…...
达梦数据库如何收集表和索引的统计信息
命令: DBMS_STATS.GATHER_TABLE_STATS(OWNNAME >HIDC,TABNAME > SYS_OSS,ESTIMATE_PERCENT>100,METHOD_OPT > FOR ALL COLUMNS SIZE AUTO,DEGREE > 2,CASCADE > true); dbms_stats.gather_table_stats:用于收集目标表,目…...
大语言模型:从诞生到未来的探索
1 发展历程 1.1 早期探索:基础积累 大语言模型的发展并非一蹴而就,其源头可以追溯到自然语言处理的早期阶段。早期的自然语言处理系统主要基于规则和模板,通过人工编写的语法规则来处理文本。例如,早期的机器翻译系统就是根据预…...
DeepSeek-V3:AI语言模型的高效训练与推理之路
参考:【论文学习】DeepSeek-V3 全文翻译 在人工智能领域,语言模型的发展日新月异。从早期的简单模型到如今拥有数千亿参数的巨无霸模型,技术的进步令人瞩目。然而,随着模型规模的不断扩大,训练成本和推理效率成为了摆在…...
【多模态】Magma多模态AI Agent
1. 前言 微软杨建伟团队,最近在AI Agent方面动作连连,前两天开源了OmniParser V2,2月26日又开源了Magma,OmniParser专注在对GUI的识别解析,而Magma则是基于多模态技术,能够同时应对GUI和物理世界的交互&…...
DeepSeek掘金——DeepSeek R1驱动的PDF机器人
DeepSeek掘金——DeepSeek R1驱动的PDF机器人 本指南将引导你使用DeepSeek R1 + RAG构建一个功能性的PDF聊天机器人。逐步学习如何增强AI检索能力,并创建一个能够高效处理和响应文档查询的智能聊天机器人。 本指南将引导你使用DeepSeek R1 + RAG构建一个功能性的PDF聊天机器人…...
DeepSeek在PiscTrace上完成个性化处理需求案例——光流法将烟雾动态可视化
引言:PiscTrace作为开放式的视图分析平台提供了固定格式的类型参数支持个性化定制处理需求,本文一步步的实现光流分析按照不同需求根据DeepSeek的代码处理视频生成数据。 光流法(Optical Flow)是一种基于图像序列的计算机视觉技术…...
explore与explode词源故事
英语单词explore来自古法语,源自拉丁语,由前缀ex-(出来)加词根plor-(叫喊)以及末尾的小尾巴-e组成,字面意思就是“喊出来,通过叫喊声赶出来”。它为什么能表示“探索”呢?…...
LeeCode题库第三十七题
37.解数独 项目场景: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请…...
【数字信号处理:从原理到应用的深度剖析】
一、数字信号处理的原理 数字信号处理(DSP)是一种通过数学算法对信号进行分析、处理和转换的技术。其核心在于对离散时间信号的操作,目的是提取有用信息或将信号转换为更易于解释的形式。 (一)信号的数字化过程 1. …...
MySQL 数据库安全配置最佳实践
文章目录 MySQL 数据库安全配置最佳实践账户与权限管理账户最小化原则权限最小化配置密码策略强化 认证与访问控制禁用匿名账户启用安全认证 网络安全防护访问源限制禁用远程root访问启用SSL加密 日志审计与监控全量审计配置二进制日志管理 服务端安全加固关键参数配置文件权限…...
小红书自动评论
现在越来越多的人做起来小红书,为了保证自己的粉丝和数据好看,需要定期养号。 那么养号除了发视频外,还需要积极在社区互动,比如点赞、评论等等,为了节省时间,我做了一个自动化评论工具。 先看效果 那这个是…...
OpenCV图像认知(一)
OpenCV: 是由Intel公司俄罗斯团队发起并参与和维护的一个计算机视觉处理开源软件库,支持与计算机视觉和机器学习相关的众多算法 OpenCV-Python: OpenCV-Python是一个Python绑定库,旨在解决计算机视觉问题。 Python是一种由Gui…...
自学微信小程序的第六天
DAY6 1、使用录音API首先需要通过wx.getRecorderManager()方法获取到一个RecorderManager实例,该实例是一个全局唯一的录音管理器,用于实现录音功能。 表32:RecorderManager实例的常用方法 方法名称 说明 start() 开始录音 pause() 暂停录音 resume() 继续录音 stop() 停止…...
C++动态与静态转换区别详解
文章目录 前言一、 类型检查的时机二、安全性三、适用场景四、代码示例对比总结 前言 在 C 中,dynamic_cast 和 static_cast 是两种不同的类型转换操作符,主要区别体现在类型检查的时机、安全性和适用场景上。以下是它们的核心区别: 一、 类…...
Qt6.8编译项目找不到文件——6.8.2\msvc2022_64\include\QtWidgets\QMainWindow does not exist.
问题:Error: dependent ‘…\Qt6.8.2\6.8.2\msvc2022_64\include\QtWidgets\QMainWindow’ does not exist. jom: D:\Temp\untitled1\build\Makefile [release] Error 2 20:20:43: 进程"D:\ProgramFiles\Develop\Qt6.8.2\Tools\QtCreator\bin\jom\jom.exe"…...
AI工具导航平台功能模块之混合分类器功能说明文档
AI工具导航平台功能模块之混合分类器功能说明文档 这是我最近正在开发的AI工具信息平台的部门功能模块混合分类器的说明文档,我的AI工具信息平台基于streamlit架构,整理出来与大家分享。 该程序的混合分类器采用规则引擎与深度学习模型协同工作的架构&…...
【时序预测】在线学习:算法选择(从线性模型到深度学习解析)
——如何为动态时序预测匹配最佳增量学习策略? 引言:在线学习的核心价值与挑战 在动态时序预测场景中(如实时交通预测、能源消耗监控),数据以流式(Streaming)形式持续生成,且潜在的…...
某个设备的RJ45网口接头为何不可连接任何POE设备
某个设备的RJ45网口接头不可连接任何POE设备 1.POE设备是什么? POE设备是指支持通过以太网线传输电力和数据的设备,即“Power over Ethernet”(PoE)技术的设备。这种技术允许网络设备在传输数据的同时,通过标准的RJ4…...
发展中的脑机接口:SSVEP特征提取技术
一、简介 脑机接口(BCI)是先进的系统,能够通过分析大脑信号与外部设备之间建立通信,帮助有障碍的人与环境互动。BCI通过分析大脑信号,提供了一种非侵入式、高效的方式,让人们与外部设备进行交流。BCI技术越…...
绕过密码卸载360终端安全管理系统
一不小心在电脑上安装了360终端安全管理系统,就会发现没有密码,就无法退出无法卸载360,很容易成为一个心病,360终端安全管理系统,没有密码,进程无法退出,软件无法卸载,前不久听同事说…...
Java数据结构第十五期:走进二叉树的奇妙世界(四)
专栏:Java数据结构秘籍 个人主页:手握风云 目录 一、二叉树OJ练习题(续) 1.1. 二叉树的层序遍历 1.2. 二叉树的最近公共祖先 1.3. 从前序与中序遍历序列构造二叉树 1.4. 从中序与后序遍历序列构造二叉树 1.5. 根据二叉树创建…...
Transformer 代码剖析9 - 解码器模块Decoder (pytorch实现)
一、模块架构全景图 1.1 核心功能定位 Transformer解码器是序列生成任务的核心组件,负责根据编码器输出和已生成序列预测下一个目标符号。其独特的三级注意力机制架构使其在机器翻译、文本生成等任务中表现出色。下面是解码器在Transformer架构中的定位示意图&…...
JAVA八股—计算机网络(自用)
JAVA八股—计算机网络(自用) 2.7 1.介绍一下TCP/IP模型和OSI模型的区别 OSI模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,将计算机网络通信划分为七个不同的层级,每个层级都负责特定的功能。每个…...
unity和unity hub关系
unity和unity hub关系 Unity和Unity Hub是紧密相关但功能不同的两个软件,以下是它们的关系说明: Unity 定义:是一款专业的实时3D开发平台,广泛用于创建各种类型的3D和2D互动内容,如视频游戏、建筑可视化、汽车设计展示、虚拟现实(VR)和增强现实(AR)应用等。功能:提供…...
Linux的OOM机制
Linux 的 OOM(Out of Memory)机制是操作系统在内存耗尽时采取的一种保护措施。当系统内存不足,无法继续分配给进程时,Linux 内核会触发 OOM 杀手(OOM Killer),选择并终止某些进程,以…...
Typora的Github主题美化
[!note] Typora的Github主题进行一些自己喜欢的修改,主要包括:字体、代码块、表格样式 美化前: 美化后: 一、字体更换 之前便看上了「中文网字计划」的「朱雀仿宋」字体,于是一直想更换字体,奈何自己拖延症…...
