(java) IO流
学习IO流之前,我们需要先认识file对象,帮助我们更好的使用IO流
1.1 file
作用:关联硬盘上的文件
 写法:
- File(String path); (推荐)
 - File(String parent, String child); //由父级路径,再子级路径拼接而成
 - File(File parent, String child);
 
路径的写法:
- 绝对路径: 从盘符开始写!!!
 - 相对路径: 不从盘符开始, 默认从项目的根目录开始关联
 
//小案例//绝对路径File file = new File("d:/a.txt");File file2 = new File("b.txt");//直接找本项目之的a.txt文件//相对路径File file3 = new File("d:/");File file4 = new File(file3,"a.txt");String str = "d:/";File file5 = new File(str,"a.txt");//补充:对于书写的斜杠,我们可以使用/和\ 
//对于/来说,linux, mac, window都使用
//对于\来说,只能适应Windows,且因为java中转义符也是\所以需要输入两个\\才能表示一个\
 
1.2 File 方法:
判断方法:
- exist 文件是否存在
 - isFile 是否为文件
 - isDirectory 是否为文件夹
 
获取方法:
-  
getName 获取文件名
 -  
getAbsolutePath 获取绝对路径
 -  
length 获取文件字节长度
 -  
lastModified 获取最后一次修改时间的毫秒值
 
创建方法:
- createdNewFile(); 
- 只能创建文件,而非文件夹,必须保证文件所在文件夹存在,否则创建失败,并且报错IOException
 - 文件存在,则会创建失败
 
 - mkdir 创建一级目录
 - mkdirs 创建多级目录
 
删除方法:
- delete() 删除文件或者文件夹, 但是文件夹必须没有内容才能删除, 否则不能删, 而且删除不走回收站
 
遍历方法:
- File[] listFile 获取文件夹的一级子目录,返回值为数组
 
遍历注意:
- 通常使用文件夹才使用该遍历方法
 - 如果是文件非要使用这个方法会得到一个null数组
 - 没有权限的文件夹我们使用该方法, 得到也是null数组
 - 文件夹里面没有内容使用这个方法的, 会得到一个长度为0的数组, 预防空指针异常()
 
//练习File file2 = new File("a.txt");//相对路径Date date1 = new Date(file2.lastModified());System.out.println(date1);//Thu Jan 02 22:08:22 CST 2025//文件创建与删除
File file1 = new File("HomeWork0102\\homeWork\\src\\cn\\itcast\\practice\\");File file2 = new File(file1,"a.txt");boolean isCreate = file2.createNewFile();//创建文件System.out.println(isCreate);boolean isDelete =  file2.delete();//删除文件System.out.println(isDelete);
//文件夹的多级创建File file3 = new File("a/b/c");//表示在当前项目下,创建a,b,c三层文件夹boolean isCreate = file3.mkdirs();System.out.println(isCreate);
//文件夹需要保证其为空才能使用delete删除//进阶-遍历某个盘,输出我们想要的文件后缀 的文件public static void main(String[] args) {System.out.println("请输入你需要查找的文件后缀,后缀之间用逗号隔开");Scanner sc = new Scanner(System.in);String str = sc.next();File file = new File("d:/");// File[] files = File.listRoots();老师使用该方法获取整个电脑的盘根目录String[] splitStrs = str.split(",");ArrayList<String> list1 = new ArrayList<>();Collections.addAll(list1, splitStrs);showFiles(list1, file);//投入查询内容和文件起始位置}public static void showFiles(ArrayList<String> list, File file) {File[] files = file.listFiles();if (files != null) { //排除全选和文件,只寻找文件夹for (File file1 : files) {//切文件,拿到文件的后缀名int index = file1.getName().lastIndexOf(".");if (index > 0) {String substring = file1.getName().substring(index);if (list.contains(substring)) {System.out.println(file1.getAbsoluteFile());}}if (file1.isDirectory()) {showFiles(list, file1);} // 如果遇到下一级文件夹,进行递归操作}}}//再补充几个案例,更好的帮助我们理解什么是递归//案例1 递归删除文件夹public static void deleteDirectory(File file) {File[] files = file.listFiles();if (files != null) {//排除权限和文件for (File file1 : files) {if (file1.isFile()) {file1.delete();} else {deleteDirectory(file1);}}}file.delete();//循环最后,删除文件夹}//方法
 
没有IO流之前,我们的数据全部存储了内存中,当程序关闭,数据消失,如果部分数据需要保留,就存放到硬盘之中,我们的JAVA想要访问硬盘,就需要一系列的本地方法。
2. IO流
作用:在硬盘上储存文件
从内容上来分,分为字符流和字节流,每一种流又分为输出流和输入流,此时的输入和输出的角度是站在内存的角度来考虑的,内存向硬盘输入数据叫输出流,从硬盘读取数据叫输入流。
2.1 字节流
(一)FileOutputStream输出流构造方法:
- FileOutputStream(String name)/FileOutputStream(String name, boolean append)
 - FileOutputStream(File file)/FileOutputStream(File file, boolean append)
 
起始底层也是把String包装为File类型进行创建,后面的布尔值表示是续写,默认为false
功能:
- 创建一个输出流对象
 - 如果关联的文件不存在则会创建, 而且底层采用是createNewFile帮你创建
 - 如果文件存在,则清空文件内容
 
- write(xxx) 能写单个元素, byte数组, byte数组的一部分
 - close(); 关闭资源,如果不关闭资源,就无法对文件进行更改
 
(二)FileInputStream输入流构造方法
-  
FileInputStream(String path);
 -  
FileInputStream(File path);
 -  
read(); 可以读一个字节,读一个byte数组,以及byte数组的一部分
补充:如果一个一个读,读不到字节就返回-1,如果一个byte数组一个数组的读,返回的值是所读到的位数,如果没有读到内容,就会返回-1。
 -  
close()关闭资源
 
//对于字节流来说,最经典的还是利用自创小数组来复制文件public static void main(String[] args) throws IOException {//利用自创小数组来复制文件
FileOutputStream fos = new FileOutputStream("rehearsal\\src\\cn\\itcast\\practice\\a.txt");
FileInputStream fis = new FileInputStream("rehearsal\\src\\cn\\itcast\\practice\\b.txt");int len;byte[] arr = new byte[8 * 1024];while ((len = fis.read(arr)) != -1) {fos.write(arr, 0, len);};fos.close();fis.close();}//main//补充:此处如果选择一个字节一个字节读取,则更改读取和输入的逻辑即可int by;while ((by = fis.read()) != -1) {fos.write(by);};//替换核心内容即可
 
2.2 缓冲字节流(非重点)
BufferedInputStream 字节缓冲输入流 语法:BufferedInputStream(InputStream in);
BufferedOutputStream字节缓冲输出流 语法:BufferedOutputStream(OutputStream out);
其的read和write跟字节输入输出流完全一样。
常见问题:
 (1) 字节流读写就是字节, 之所以能看到字符是因为文本编辑器进行解码的动作!!!
 (4) IO只能操作文件不能操作文件夹, 否则就会出现拒绝访问错误!!!
为什么不用字节缓冲流?
因为其底层还是在使用字节输入输出流,只不过通过一个byte数组读取和存取数据,减少了与硬盘的交互次数,但是字节缓冲流的读取速度还是比不上使用小数组读取数据的字节流,因为增加了数据的倒手次数。
//优秀案例:文件加密(涉及后面一点点^ 异或运算的内容)public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("homeWork\\src\\cn\\itcast\\practice\\c.txt");//写入FileInputStream fis = new FileInputStream("homeWork\\src\\cn\\itcast\\practice\\a.txt");//读取int password = 10;int by;while ((by = fis.read()) != -1) {fos.write(by ^ password);}fis.close();fos.close();}//如果为了提高效率,可以使用自定义小数组进行包装,其核心代码快int password = 110;int len;byte[] arr = new byte[8 * 1024];while (( len = fis.read(arr)) != -1){for (int i = 0; i < arr.length; i++) {arr[i] *= arr[i] ^ password;}fos.write(arr,0,len);}
 
2.3 字符流
硬盘只认识字节, 不认识字符, 我的字符流的所有写的功能都是写到了底层的缓冲字符数组中了, 并没有直接写到硬盘,
(一)Reader(抽象类) —> FileReader
 构造:
-  
FileReader(File file)
 -  
FileReader(String fileName)
 
方法:
- int read(); 一次读一个字符
 - int read(char[] arr) 一次读多个字符, 返回读到的有效字符个数
 
(二)Writer(抽象类) —> FileWriter
 构造:
-  
FileWriter(File file)
 -  
FileWriter(String fileName)
 -  
FileWriter(File file, boolean append)
 -  
FileWriter(String fileName, boolean append)
 
功能:
- write(xxx); //写单个字符, 多个字符, 多个字符的一部分,字符串, 字符串的一部分
 - close(); //关闭资源,并且简化缓冲区中是否有内容, 如果有则先刷新在关闭!!!
 - flush(); //我们需要手动调用flush方法,这个方法可以对照码表将字符编码成字节, 然后才能保存到硬盘
 
2.4 缓冲字符流(重点)
BufferedReader(Reader reader);
 方法:
 int read();
 int read(char[] arr);
 String readLine(); //一次读一行 ,此时如果读完最后一行,返回值为null
BufferedWriter(Writer writer);
 方法:
 write(xxx) 单个字符, 多个字符, 多个字符的一部分, 字符串, 字符串一部分
 newLine(); 可以根据操作系统写换行符:【不同系统的换行符不同window: \r\nlinux: \nmac: \r】
//BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\javaprojects\\HomeWork0102\\homeWork\\src\\cn\\itcast\\practice\\c.txt"));bw.write("这是一句诗歌");bw.newLine();bw.write("我又写了一句诗歌");bw.newLine();bw.write("再多写几句诗歌");bw.close();BufferedReader br = new BufferedReader(new FileReader("D:\\javaprojects\\HomeWork0102\\homeWork\\src\\cn\\itcast\\practice\\c.txt"));String str;while ( (str =br.readLine()) != null){System.out.println(str);}
 
2.5 补充:释放资源的异常捕获
对于我们一般的情况之下,遇到异常是直接抛出,不影响我们进一步书写代码,但是如果非要处理,我们可能需要自己try catch捕获,对于输入流/输出流来说,其无论报错与否都希望其正常释放资源,所有引入finally,对于输入和输出来说,可能还得分别包裹其再书写try catch逻辑,我们JDK1.8提供了新语法,可以将需要释放资源的语法放到try后的小括号中,需要确定其有.close()方法,此语法无需后续书写释放资源。
//jdk1.7及以前private static void demo1() {FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\颈椎操.flv");fos = new FileOutputStream("day12_io/a.flv");byte[] arr = new byte[1024 * 8];long start = System.currentTimeMillis();int len;while ((len = fis.read(arr)) != -1) {fos.write(arr, 0, len);}long end = System.currentTimeMillis();System.out.println(end - start);} catch (IOException e) {throw new RuntimeException(e);} finally {//释放资源try {if (fis != null) fis.close();} catch (IOException e) {throw new RuntimeException(e);}try {if (fos != null) fos.close();} catch (IOException e) {throw new RuntimeException(e);}}}//新语法public static void main(String[] args) {try (
FileInputStream fis = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\颈椎操.flv");
FileOutputStream fos = new FileOutputStream("day12_io/a.flv");) {byte[] arr = new byte[1024 * 8];long start = System.currentTimeMillis();int len;while ((len = fis.read(arr)) != -1) {fos.write(arr, 0, len);}long end = System.currentTimeMillis();System.out.println(end - start);} catch (IOException e) {throw new RuntimeException(e);}}
 
3. 其他流(了解)
3.1 转换流
转换流:(才是真正的字符流, 而我们学习的FileReader和FileWriter其实是字符流的便捷流)
优势: 指定编码表进行读写操作!!!,但是已经淘汰了
 世间没有字符流, 因为磁盘只认识字节, 所谓的字符流 = 字节流 + 码表
InputStreamReader 构造:
 InputStreamReader(InputStream in, String charsetName);
OutputStreamWriter 构造:
 OutputStreamWriter(OutputStream out,String charsetName )
 剩下的功能和FileReader和FileWriter 一模一样
3.2 打印流
本质就是一条输出流
 PrintStream, PrintWriter
 构造:
 PrintStream(String path);
方法:
 write(xxx); 写单个字节, 写多个字节, 写多个字节的一部分
 println(xxx); 原样写东西,并换行
 print(xxx); 原样写东西
 close(); 释放资源
3.3 数据流
优势:可以将多个数据之间使用一个特殊的分隔符存放, 将数据一帧一帧存放, 一帧一帧的读取!!!
DataInputStream: 数据输入流
 构造: DataInputStream(InputStream in);
功能:
 readXxx(); 将数据一帧一帧的读取出来
 DataOutputStream: 数据输出流
 构造: DataOutputStream(OutputStream out);
 功能:
 writeXxx(xxx); 将数据一帧一帧写出去
3.4 对象流:(序列化流)
对象输入流(反序列化流)
 ObjectInputStream(InputStream in);
 对象输出流(序列化流)
 ObjectOutputStream(OutputStream out);
补充概念:
 什么序列化: 将对象从内存中保存磁盘的过程我们称为序列化
 什么是反序列化: 将磁盘中的数据恢复到内存的过程我们称为反序列化
注意事项:
 对象想要保存到硬盘中必须实现Serializable接口, 一旦实现这个接口之后, 默认会生成一个序列化ID,这个id默认跟你类中组成部分算出来
 构造, 成员变量,成员方法, 内部类, 代码块, 但是修改了任何的内容, 这个序列化id就会变化, 如果反序列化的时候你的类中的当前的id跟你当时保存的时候id不一致就会报错,检测到你的类的内容改变了!!!
 我们可以让这个id跟类的组成部分没关系即可!!!,不要让系统生成, 你手动给出序列化id即可
相关文章:
(java) IO流
学习IO流之前,我们需要先认识file对象,帮助我们更好的使用IO流 1.1 file 作用:关联硬盘上的文件 写法: File(String path); (推荐)File(String parent, String child); //由父级路径,再子级路径拼接而成File(File p…...
2025年1月个人工作生活总结
本文为 2025年1月工作生活总结。 研发编码 使用sqlite3命令行查询表数据 可以直接使用sqlite3查询数据表,不需进入命令行模式。示例如下: sqlite3 database_name.db "SELECT * FROM table_name;"linux shell使用read超时一例 先前有个编译…...
线性调整器——耗能型调整器
线性调整器又称线性电压调节器,以下是关于它的介绍: 基本工作原理 线性调整器的基本电路如图1.1(a)所示,晶体管Q1(工作于线性状态,或非开关状态)构成一个连接直流源V和输出端V。的可调电气电阻,直流源V由60Hz隔离变压器(电气隔离和整流&#…...
【2025美赛D题】为更美好的城市绘制路线图建模|建模过程+完整代码论文全解全析
你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 作为经验丰富的美赛O奖、国赛国一的数学建模团队,我们将为你带来本次数学建模竞赛的全面解析。这个解决方案包不仅包括完整的代码实现,还有详尽的建模过程和解析,…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.28 存储之道:跨平台数据持久化方案
好的,我将按照您的要求生成一篇高质量的Python NumPy文章。以下是第28篇《存储之道:跨平台数据持久化方案》的完整内容,包括目录、正文和参考文献。 1.28 存储之道:跨平台数据持久化方案 目录 #mermaid-svg-n1z37AP8obEgptkD {f…...
拼车(1094)
1094. 拼车 - 力扣(LeetCode) 解法: class Solution { public:bool carPooling(vector<vector<int>>& trips, int capacity) {uint32_t passenger_cnt 0;//将原数据按照from排序auto func_0 [](vector<int> & …...
基于Python的人工智能患者风险评估预测模型构建与应用研究(下)
3.3 模型选择与训练 3.3.1 常见预测模型介绍 在构建患者风险评估模型时,选择合适的预测模型至关重要。不同的模型具有各自的优缺点和适用场景,需要根据医疗数据的特点、风险评估的目标以及计算资源等因素进行综合考虑。以下详细介绍几种常见的预测模型。 逻辑回归(Logisti…...
< OS 有关 > Android 手机 SSH 客户端 app: connectBot
connectBot 开源且功能齐全的SSH客户端,界面简洁,支持证书密钥。 下载量超 500万 方便在 Android 手机上,连接 SSH 服务器,去运行命令。 Fail2ban 12小时内抓获的 IP ~ ~ ~ ~ rootjpn:~# sudo fail2ban-client status sshd Status for the jail: sshd …...
向量和矩阵算法笔记
向量和矩阵算法笔记 Ps:因为本人实力有限,有一部分可能不太详细,若有补充评论区回复,QWQ 向量 向量的定义 首先,因为我刚刚学到高中的向量,对向量的看法呢就是一条有长度和方向的线,不过这在数学上的定义其实是不对,甚至跟我看的差别其实有点大,真正的定义就是数域…...
uniapp使用uni.navigateBack返回页面时携带参数到上个页面
我们平时开发中也经常遇到这种场景,跳转一个页面会进行一些操作,操作完成后再返回上个页面同时要携带着一些参数 其实也很简单,也来记录一下吧 假设从A页面 跳转到 B页面 A页面 直接上完整代码了哈,很简单: <t…...
Python 梯度下降法(二):RMSProp Optimize
文章目录 Python 梯度下降法(二):RMSProp Optimize一、数学原理1.1 介绍1.2 公式 二、代码实现2.1 函数代码2.2 总代码 三、代码优化3.1 存在问题3.2 收敛判断3.3 函数代码3.4 总代码 四、优缺点4.1 优点4.2 缺点 Python 梯度下降法ÿ…...
Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年
Android Studio 1.0 宣发于 2014 年 12 月,而现在时间来到 2025 ,不知不觉间 Android Studio 已经陪伴 Androider 走过十年历程。 Android Studio 10 周年,也代表着了我的职业生涯也超十年,现在回想起来依然觉得「唏嘘」ÿ…...
sem_wait的概念和使用案列
sem_wait 是 POSIX 标准中定义的一个用于同步的函数,它通常用于操作信号量(semaphore)。信号量是一个整数变量,可以用来控制对共享资源的访问。在多线程编程中,sem_wait 常用于实现线程间的同步。 概念 sem_wait 的基…...
集合的奇妙世界:Python集合的经典、避坑与实战
集合的奇妙世界:Python集合的经典、避坑与实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进&#x…...
专业视角深度解析:DeepSeek的核心优势何在?
杭州深度求索(DeepSeek)人工智能基础技术研究有限公司,是一家成立于2023年7月的中国人工智能初创企业,总部位于浙江省杭州市。该公司由量化对冲基金幻方量化(High-Flyer)的联合创始人梁文锋创立,…...
MySQL 索引存储结构
索引是优化数据库查询最重要的方式之一,它是在 MySQL 的存储引擎层中实现的,所以 每一种存储引擎对应的索引不一定相同。我们可以通过下面这张表格,看看不同的存储引擎 分别支持哪种索引类型: BTree 索引和 Hash 索引是我们比较…...
【ComfyUI专栏】如何使用Git命令行安装非Manager收录节点
当前的ComfyUI的收录的自定义节点很多,但是有些节点属于新出来,或者他的应用没有那么广泛,Manager管理节点 有可能没有收录到,这时候 如果我们需要安装需要怎么办呢?这就涉及到我们自己安装这些节点了。例如下面的内容…...
python算法和数据结构刷题[1]:数组、矩阵、字符串
一画图二伪代码三写代码 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中)-CSDN博客 算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn) 面试经典 150 题 - 学习计…...
数据分析系列--④RapidMiner进行关联分析(案例)
一、核心概念 1.项集(Itemset) 2.规则(Rule) 3.支持度(Support) 3.1 支持度的定义 3.2 支持度的意义 3.3 支持度的应用 3.4 支持度的示例 3.5 支持度的调整 3.6 支持度与其他指标的关系 4.置信度࿰…...
1/30每日一题
从输入 URL 到页面展示到底发生了什么? 1. 输入 URL 与浏览器解析 当你在浏览器地址栏输入 URL 并按下回车,浏览器首先会解析这个 URL(统一资源定位符),比如 https://www.example.com。浏览器会解析这个 URL 中的不同…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
