JAVAEE之文件IO_数据流概念,字节流:InputStream、OutputStream,字符流:reader、writer,及实例代码

什么是数据流

 顾名思义,I 表示input,O 表示output,也就是输入输出流,主要是在程序与文件之间,用于传输数据的通道。既然要传输数据,那么我们需要理解文件和程序之间哪种方向的传输是输入流,哪种传输作为输出流?我们可以举一个例子,如下图所示:
在这里插入图片描述
 IO 流是 Java IO 中的核心概念。流是在概念上表示无穷无尽的数据流。IO 流连接到数据源或数据的目的地,连接到数据源的叫输入流,连接到数据目的地的叫输出流。Java 程序不能直接从数据源读取和向数据源写入,只能借助 IO 流从输入流中读取数据,向输出流中写入数据。
 Java IO 中的流可以是基于字节的(读取和写入字节)也可以基于字符的(读取和写入字符),所以分为字节流和字符流,两类流根据流的方向都可以再细分出输入流和输出流。
注意:这里的输入、输出是站在CPU的角度。


一、字节流

 字节流主要操作字节数据或二进制对象。字节流有两个核心抽象类:InputStream 和 OutputStream。所有的字节流类都继承自这两个抽象类。

1.1 输入字节流:InputStream

 InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream
常用的方法
在这里插入图片描述
参考实例代码:

package CharStream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class Demo3 {public static void main(String[] args) {//1、创建File对象try(InputStream inputStream = new FileInputStream("D:/text.txt")){byte[] buffer = new byte[1024];int n = inputStream.read(buffer);   //2、读取文件内容System.out.println("n:"+n);for (int i = 0; i < n; i++) {System.out.printf("%x\n",buffer[i]);}} catch (IOException e) {throw new RuntimeException(e);}}
}

利用 Scanner 进行字符读取

 我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类。

package CharStream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;public class Demo5 {public static void main(String[] args) {try(InputStream inputStream = new FileInputStream("d:/text.txt")){//此时scanner就是从文件中读取了!!Scanner scanner = new Scanner(inputStream);String s = scanner.next();System.out.println(s);} catch (IOException e) {throw new RuntimeException(e);}}
}

1.2 输出字节流:OutputStream

构造方法:
在这里插入图片描述
 OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream。
常用方法
在这里插入图片描述
参考实例代码:

package CharStream;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Demo4 {public static void main(String[] args) {//1. 打开文件,如果文件存在,会清除文件的内容,如果文件不存在,就会创建新文件try(OutputStream outputStream  = new FileOutputStream("d:/text.txt",true)){String s= "你好世界";//2. 使用wirte方法写入内容,字符串调用getBytes()方法可以得到字符串对应的字节数组outputStream.write(s.getBytes());    //和writer类似,OutPutStream打开一个文件,就会默认清空文件的原有内容,如果不想清空,在构造方法中第二个参数传入true//3. 关闭文件} catch (IOException e) {throw new RuntimeException(e);}}
}

 上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用PrintWriter 类来完成输出,因为PrintWriter 类中提供了我们熟悉的 print/println/printf 方法。
参考实例代码如下:

package CharStream;import java.io.*;
public class Demo6 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("d:/text.txt")){//这里就相当于把字节流转成字符流了PrintWriter writer = new PrintWriter(outputStream);writer.println("hello");writer.flush();   //} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}

二、 字符流

 上面的字节流是以字节为单位读写文件数据,但是对unicode字符来说,中文字符占了两个字节,处理不当会出现“乱码”现象。
 字符流操作的是字符,字符流有两个核心类:Reader 类和 Writer 。所有的字符流类都继承自这两个抽象类。

2.1 输入字符流: Reader

字符流输入流作用:读取文件内容。
参考实例代码:

package CharStream;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;public class Demo1 {/*** 字符流* read* @param args* @throws IOException*/public static void main(String[] args) throws IOException {//  Reader reader = new FileReader("d:/text.txt");/*** 1.一次read一个字符** while(true){*             int c  = reader.read();   //无参数read,一次只返回一个字符*             if (c== -1){*                 //读取完毕*                 break;*             }*             char ch = (char) c;*             System.out.println(ch);*         }*/try{//2.一次read多个字符while(true){char[] cubf = new char[1024];int n = reader.read(cubf);* n表示当前读取到的字符的个数*  一个参数read:一次读取若干个字符,会把参数指定的cbuf数组给填充满*  应该往这个read里传入的是一个空的字符数组,然后由read方法内部对这个数组内容进行填充,次数"cbhf"这个参数,称为”输出型参数·“if (n== -1){//完毕读取break;}System.out.println("n = "+n);for (int i = 0; i < n; i++) {System.out.println(cubf[i]);}}}finally {reader.close();//3. 一个文件使用完了,要记得close (使用close方法,最主要的方法是为了释放文件描述符)}*///try with resources语法的目的 :()定义的变量,会在try代码快结束的时候(无论是正常结束还是抛异常),自动调用其中的close方法try(Reader reader = new FileReader("D:/text.txt") ){while(true){char[] cubf = new char[3];int n = reader.read(cubf);if (n == -1){break;}System.out.println("n:"+n);for (int i = 0; i < n; i++) {System.out.println(cubf[i]);}}}// reader.read();   //三个参数read:一次读取若干个字符,会把参数执行的cbuf数组中的off这个位置开始,到len这么长的范围内填满}
}

2.2 输出字符流:Writer

参考代码实例:

package CharStream;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;/*** @author Zhang* @date 2024/5/1620:23* @Description:*/
public class Demo2 {/***字符流* write* @param args*/public static void main(String[] args) {try(Writer writer = new FileWriter("d:/text.txt",true);) {writer.write("我在学习IO");  //写入文件,默认会把原来的内容清空,解决办法加true} catch (IOException e) {throw new RuntimeException(e);}}
}

三、 字节流、字符流怎么选择?

 字节流和字符流都有 read()、write()、flush()、close() 这样的方法,这决定了它们的操作方式近似。
 字节流的数据是字节(二进制对象)。主要核心类是 InputStream 类和 OutputStream 类。字符流的数据是字符,主要核心类是 Reader 类和 Writer 类。所有的文件在硬盘或传输时都是以字节方式保存的,例如图片,影音文件等都是按字节方式存储的。字符流无法读写这些文件。
 所以,除了纯文本数据文件使用字符流以外,其他文件类型都应该使用字节流方式。字节流到字符流的转换可以使用 InputStreamReader 和 OutputStreamWriter。使用 InputStreamReader 可以将输入字节流转化为输入字符流,使用OutputStreamWriter可以将输出字节流转化为输出字符流。

相关练习:扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件:

package CharStream;import java.io.File;
import java.util.Scanner;/*** @author Zhang* @date 2024/5/1715:28* @Description:*/
public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 1. 先让用户输入一个要扫描的目录System.out.println("请输入要扫描的路径");String path = scanner.next();//判断路径是否存在File rootPath = new File(path);if (!rootPath.isDirectory()){System.out.println("您输入的扫描的路径有误");return;}//2.再让用户输入一个要查询的关键词System.out.println("请输入要删除文件的关键词");String word = scanner.next();//3. 进行递归扫描,这个方法进行递归scanDir(rootPath,word);}private static void scanDir(File rootPath, String word) {//1. 先列出rootPath 中的所有文件和目录File[] files = rootPath.listFiles();if(files  == null){///当前目录为空,就可以直接返回了return;}//2. 遍历这里的每个元素,针对不同各类型做出不同的处理for (File f: files){System.out.println("当前扫描的文件:"+f.getAbsolutePath()); //加个日志,方便观察当前递归的执行过程if (f.isFile()){//普通文件,检查是否要被删除,并执行删除操作checkDelete(f,word);}else {//目录,运用递归再去判定子目录里包含的内容scanDir(f,word);}}}private static void checkDelete(File f, String word) {if (!f.getName().contains(word)){//不必删除,直接方法结束return;}//需要删除System.out.println("当前文件为:"+f.getAbsolutePath() +",确认是否要删除");Scanner scanner  = new Scanner(System.in);String choice = scanner.next();if (choice.equals("Y") || choice.equals("y")){//真正执行删除操作f.delete();System.out.println("删除完毕!");}else{//如果出入其他值,不一定是n,都会取消删除操作System.out.println("取消操作!");}}
}

总结

文件IO流框架:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/21710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统(3) 处理机调度

目录 一、处理机调度概述 1.基本准则 &#xff08;1&#xff09;CPU利用率 &#xff08;2&#xff09;系统吞吐量 &#xff08;3&#xff09;周转时间 &#xff08;4&#xff09;等待时间 &#xff08;5&#xff09;响应时间 2.进程调度方式 &#xff08;1&#xff0…

现代密码学-数字签名

从消息认证码到数字签名 前面讲到&#xff0c;消息认证码无法防止否认&#xff0c;A,B之间共享密钥计算出MAC,A,B都能计算出MAC,对于第三方C来说&#xff0c;他无法证明这个MAC是A计算的还是B计算的。 通过数字签名解决问题。 A,B各自使用不同的密钥-公钥密码&#xff0c;A用…

LeetCode刷题之HOT100之组合总和

2024/6/3 周一&#xff0c;工作日的第一天。昨晚梦到被导师说去实验室不积极哈哈哈&#xff0c;风扇开到二级&#xff0c;早上被吹醒。买的书马上快要到了。上午刚来准备刷题&#xff0c;结果去搞了一下数据库sql&#xff0c;做的差不多了&#xff0c;还差点格式转换就差不多出…

军用电源性能测试有哪些测试项目?需要遵循什么标准?

为了确保军用电源在极端条件下能够正常工作&#xff0c;必须对其进行一系列严格的性能测试。这些测试不仅包括效率、电压调整率和负载调整率等基本参数的测试&#xff0c;还包括动态响应能力、绝缘电阻、耐压测试、温度系数以及高低温循环等综合性能的评估。 测试项目 效率 电压…

MySQL -- 连接查询

MySQL使用连接查询&#xff08;JOIN&#xff09;是为了从多个相关表中获取数据。连接查询是一种强大且常用的操作&#xff0c;可以根据某些条件将两张或多张表中的数据组合在一起&#xff0c;返回一个联合结果集。 1.为什么使用连接查询 数据规范化&#xff1a; 数据库设计时通…

站点被篡改快照被劫持解决服务方法教程_一招制敌

站点被篡改快照被劫持解决服务方法教程_一招制敌 被篡改表现形式&#xff1a; 站点打不开或跳转到别的网站。 攻击者目的&#xff1a; 报复、勒索、卖防御产品&#xff08;如DDOS防御产品&#xff09;。 攻击成本&#xff1a; 工具&#xff08;如VPN购买&#xff09;成本、人…

智能工厂生产设备实时监控技术的UI设计

智能工厂生产设备实时监控技术的UI设计

Flutter的Dart语法入门

文章目录 前言1. 类型声明2. 数据类型2.1 基本数据类型常量 2.2 String2.3 集合2.4 unicode 3. Dart函数特征3.1 可变参数列表和默认入参3.2 匿名函数3.3 typedef 4. Dart面向对象4.1 构造函数4.2 访问权限4.3 类的继承 参考资料附录 前言 每个语言都有控制流语句就不写测试代…

房地产vr全景展示交互视频让购房者更有参与感

在当今房地产市场中&#xff0c;购房者的需求日益多样化和个性化。为满足这一趋势&#xff0c;我们创新性地将VR虚拟现实技术应用于楼盘宣传&#xff0c;为购房者带来前所未有的沉浸式购房体验。 一、地理位置全景展示 通过实景拍摄与VR技术的结合&#xff0c;我们为购房者呈现…

day26-单元测试

1. 单元测试Junit 1.1 什么是单元测试&#xff1f;&#xff08;掌握&#xff09; 1.2 Junit的特点&#xff1f;&#xff08;掌握&#xff09; 1.3 基本用法&#xff1a;&#xff08;掌握&#xff09; 实际开发中单元测试的使用方式&#xff08;掌握&#xff09; public class …

C语言,排序

前言 排序&#xff0c;可以说是数据结构中必不可缺的一环。我们创造数据存储它&#xff0c;要想知道数据之间的联系&#xff0c;比较是必不可少的。不然&#xff0c;费劲心思得来的数据若是不能有更多的意义&#xff0c;那么拿到了又有什么用&#xff1f; 排序是计算机内经常进…

风险投资公司正在帮助小投资者购买Anthropic、OpenAI等热门公司的股票

近年来&#xff0c;风险投资公司对于人工智能&#xff08;AI&#xff09;领域的公司&#xff0c;如Anthropic、Groq、OpenAI等&#xff0c;表现出了极高的投资热情。这些公司因为它们在AI技术方面的创新而备受瞩目。但是&#xff0c;对于很多小投资者来说&#xff0c;由于资金有…

[C#]使用C#部署yolov8的目标检测tensorrt模型

【测试通过环境】 win10 x64 vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super 版本和上述环境版本不一样的需要重新编译TensorRtExtern.dll&#xff0c;TensorRtExtern源码地址&#xff1a;TensorRT-CShar…

期权的权利金怎么算的

期权权利金的计算涉及多个因素&#xff0c;包括敲定价格、到期时间以及整个期权合约的具体情况。期权的权利金具体的计算公式和因素可能因不同的期权合约和市场条件而有所不同&#xff0c;下文为大家介绍期权的权利金怎么算的 &#xff1f;本文来自&#xff1a;期权酱 一、期权…

【LeetCode】二叉树oj专题

如有不懂的地方&#xff0c;可查阅往期相关文章&#xff01; 个人主页&#xff1a;小八哥向前冲~ 所属专栏&#xff1a;数据结构【c语言】 目录 单值二叉树 对称二叉树 计算二叉树的深度 二叉树的前序遍历 相同二叉树 另一棵树的子树 二叉树的构建和遍历 翻转二叉树 判…

spring boot 中的异步@Async

spring boot 开启异步调用 1、启动类上添加EnableAsync注解&#xff0c;表示启动异步 2、在具体实现异步的方法上添加Async注解 package com.example.demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootAppli…

YOLOv3+mAP实现金鱼检测

YOLOv3mAP实现金鱼检测 Git源码地址&#xff1a;传送门 准备数据集 按帧数读取视频保存图片 video2frame.py使用labelimg标注工具对图片进行标注统一图片大小为 416x416&#xff0c;并把标签等信息写成.xml文件 conver_point.py读取缩放后的标签图片&#xff0c;转为左上角右下…

如何快速部署上线项目

CSDN 的小伙伴们&#xff0c;大家好呀&#xff0c;我是苍何。 今天在群里面看到有小伙伴反馈说&#xff0c;面试的时候一被问到简历中的项目还没上线&#xff0c;就不继续问了&#xff0c;感觉挺奇葩的&#xff0c;要知道就校招来说&#xff0c;项目本身大部分都是练手的项目&…

Linux基础1-基本指令3

上篇文章我们说到了文件&#xff0c;pwd&#xff0c;touch&#xff0c;mkdir等知识。 Linux基础1-基本指令2&#xff08;你真的了解文件吗?&#xff09;-CSDN博客 本文继续梳理其他基础命令 1.本章重点 1.删除一个空目录命令rmdir 2.删除一个文件指令rm(重要!) 3.man命令&am…

做视频号小店保证金要交多少?保证金提现条件是什么?

大家好&#xff0c;我是喷火龙。 做视频号小店也是需要缴纳保证金的&#xff0c;保证金分为类目保证金和浮动保证金。 先来说说类目保证金&#xff0c;类目保证金由视频号小店主体资质类型和经营商品类目决定。 类目保证金有以下三点需要注意&#xff1a; 1. 如果你要申请新…