【Java】韩顺平Java学习笔记 第19章 IO流

news2025/1/13 10:03:54

文章目录

  • 文件概述
  • 常用的文件操作
    • 创建文件
    • 获取文件信息
    • 目录的操作和文件删除
    • 流的分类
    • 各抽象类常用子类对象
      • FileInputStream
      • FileOutputStream
      • FileReader
      • FileWriter
  • 节点流和处理流
    • 概念
    • BufferedReader
    • BufferedWriter
    • BufferedInputStream & BufferedOutputStream
  • 对象流:ObjectInputStream & ObjectOutputStream
  • 标准输入输出流:System.in & System.out
  • 转换流:InputStreamReader & OutputStreamWriter
    • 常用方法
  • 打印流:PrintStream & PrintWriter
    • 常用方法(PrintStream 和 PrintWriter通用 )
    • 与直接使用 write 方法的区别
  • Properties类
    • 常用方法

文件概述

  • 保存数据的地方
  • 文件流:文件在程序中是以流的形式操作的
  • 输入流:数据从数据源(文件)到程序(内存)的路径,输出流相反

常用的文件操作

创建文件

  • new File(String pathname) 文件的路径
  • new File(File Parent,String child ) 父目录文件+子路径(文件名)
  • new File(String parent, String child)父目录+子路径
  • 上面是创建文件对象,使用创建方法才能真正创建文件:createNewFile() [需要异常处理]

获取文件信息

  • getName 文件名
  • getAbsolutePath 绝对路径
  • getParent 文件父级目录
  • length 文件大小(字节)
  • exist
  • isFile
  • isDirectory 文件是不是一个目录(文件夹)

目录的操作和文件删除

  • delete (返回boolean 是否删除成功)
  • 在Java中,目录也被当成文件
  • mkdir 创建一级目录**(注意创建文件夹的方法和创建文件不同!)**
  • mkdirs 创建多级目录

流的分类

  • 操作数据单位不同:字节流(8 bit,操作二进制文件时无损操作),字符流(操作文本文件效率更高)

  • 数据流的流向不同:输入流,输出流

  • 流的角色不同:节点流,处理流/包装流

  • 字节输入流:InputStream

    字节输出流:OutputStream

    字符输入流:Reader

    字符输出流:Writer

    上面四个都是抽象类

  • 流和文件的关系:流是文件/程序之间传递信息的介质

各抽象类常用子类对象

FileInputStream

  • read 一个个字节读,返回-1到达文件末尾,注意一个汉字有三个字节
  • 优化减少读取的次数:read(byte[ ] b) 一次最多读取b.length字节的数据到字节数组,返回实际读取的字节数,返回-1说明读取完毕
  • close 关闭文件

FileOutputStream

  • write 写入一个字节

  • String 的 getBytes 可以将字符串转换为字符数组,可以配合write写入字符串

  • write(byte[ ] b)

  • write(byte[ ] b,index1,index2) index为读取字节的起点和终点

  • new 的创建方式,当写入内容时,会覆盖原来的内容

  • new FileOutputStream(filePath,true)的创建方式,写入内容时,在原来的文本后追加

    true 传给参数 append

FileReader

  • 按照字符来操作io,汉字不会乱码
  • new FileReader(File/String,(true)) 可选true,追加模式,需要处理异常
  • 读取方式基本和FileInputStream相同
  • read
  • read(char[ ])
  • new String (char[ ]) 将char转换成String
  • new String(char[ ],off,len)
  • close

FileWriter

  • new FileWriter(File/String,(true)) 可选true,追加模式
  • 注:写完之后必须关闭流(close)或者刷新(flush),才能真正写到文件中(看源码)
  • write(int)
  • write(char[ ])
  • write(char[ ],off,len)
  • write(string)
  • write(string,off,len)(注:off为写入的起始位置)

节点流和处理流

概念

  • 节点流:从某一特定数据源读写数据,如FileReader、FileWriter,但限制较多,功能不强大

  • 处理流(包装流):对节点流进行包装,“连接”已存在的流(节点流或处理流),如BufferedReader、BufferedWriter

    BufferedReader 里面有一个 Read 类型的对象,代表其以后可以实现 Read 的各子类如FileReader、CharReader、StringReader等,使其能够处理各种数据,功能更强大

    使用了修饰器模式

  • 区别和联系

    • 节点流是底层流,直接与数据源相连
    • 处理流包装节点流,通过一个节点流,传入不同的节点流,来统一处理文件的流(都使用处理流),即想处理字符串就把处理字符串的节点流(如StringReader)传入处理流(BufferedReader),想处理数组就把处理数组的节点流(ByteArrayInputStream)传入处理流(BufferedReader),否则每种节点流还需单独创建一个对象。并且还可以拓展输入输出的方式
    • 处理流不直接于数据源相连,而是调用了节点流的方法**(多态和动态绑定)**
  • 处理流优点

    • 提高性能:以增加缓冲的方式来提高输入输出的效率
    • 操作便捷:可能提供一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
  • 要知道什么情况下用什么流!

BufferedReader

  • ​ 和 BufferedWriter 一样是字符流,尽量操作文本文件,不操作二进制文件(图片、音乐等),否则可能造成文件损坏
  • 关闭时关闭外层流即可,即关闭BufferedReader即可,不用关闭内层的节点流(如FileReader),因为关闭外层流的close方法里面调用了节点流的close方法
  • readline 按行读取,效率高,当返回 null 时,读取完毕(看手册),不带换行(用newline手动换行)

BufferedWriter

  • newLine 插入一个和系统相关的换行(不同系统换行不同,因此不建议用\n换行符)
  • 如果要追加,在传入节点流(FileWriter)时传入true,即new BufferedWriter(new FileWriter( path, true))

BufferedInputStream & BufferedOutputStream

  • 字节流,可以操作二进制文件也可以操作文本文件
  • 操作与之前的几个类类似

对象流:ObjectInputStream & ObjectOutputStream

  • 需求:保存数据时同时保存其数据类型(序列化,即把对象保存为文件。从文件恢复为对象称为反序列化

  • 必须让某个类是 可序列化的,有两个方式:

    • 实现 Serializable 接口(推荐,标记接口,没有任何方法)
    • 实现 Externalizable 接口
  • ObjectOutputStream 提供 序列化功能

  • ObjectInputStream 提供 反序列化功能

  • 序列化后,保存的文件格式,是按照其实际格式保存

  • 包装类(如 Integer、Double)和 String 都实现了 Serializable 接口

  • 各种方法与之前的类相似

    需要注意读写文件时需要加上数据类型,如:writeInt、writeDouble、readBoolean、readChar

  • 读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致

  • 需要将自定义数据类型(类)的定义拷贝(或导包)到可以引用的位置(注意该类不要用 private 修饰),这样调用过后才能直接用这个自定义数据类型

  • 如果要调用自定义数据类型的方法,需要向下转型,因为从文件调进来的是Object类型

  • 序列化的类中建议添加 SerialVersionUID (序列版本号),提高序列化兼容性

  • static 和 transient(标记这个变量不应序列化) 修饰的成员不会被序列化

    • transient 使用场景
      • 安全:密码、安全令牌等不应该持久化或通过网络传输
      • 性能:大对象或不重要的对象成员没必要序列化
      • 逻辑需求:某对象只可能对特定上下文有意义,无需序列化
    • 注意事项
      • transient 只能用于变量,不能用于方法和类
      • 局部变量(方法内变量)不能用 transien 修饰,因为局部变量本来就不会被序列化
  • 序列化对象时,要求里面属性的类型(如另一个类的对象)也需要实现序列化接口,即使其被 transient 修饰,不会被序列化,也要实现这个接口

  • 序列化具有可继承性,如某类实现了序列化,则其子类默认实现序列化

  • 注意每次 new 的时候都会调用writeStreamHeader()方法写入4个字节的StreamHeader(看源码),标记这个是对象处理流,可能导致的错误:如果在接收方每次都是new一个新的ObjectInputStream 来接收,而发送方只 new 过一个 ObjectOutputStream,之后每次都是用new过的 ObjectOutputStream对象来发送东西,这样就会导致之后并没有添加头部。而接受方每次都是新的 new,则每次接收都要检测头部,当发送方没有提供头部时,接收方就把内容当做了头部,导致出错。解决方法之一是每次使用 ObjectOutputStream 时都重新 new 一遍

标准输入输出流:System.in & System.out

  • 标准输入(键盘):System.in,InputStream的流对象(编译类型),运行类型是BufferedInputStream

  • 标准输出(显示器):System.out,编译类型和运行类型都是PrintStream,是PrintStream类的一个对象

  • 不需要显式关闭

    • 它们与程序生命周期有关,程序开始运行时由操作系统自动打开,程序终止时也由操作系统自动关闭,无需用户手动操作
    • 标准流通过JVM管理
    • 方便使用
    • 避免以后需要调用时抛出异常
  • System.setOut(new PrintStream(filePath)) 修改标准输出流的打印位置,打印到文件

    filePathSystem.out 代替,则打印到屏幕)

转换流:InputStreamReader & OutputStreamWriter

  • InputStreamReader:将字节流转换成字符流输入到程序,并且根据指定的编码方式转换为字符
  • OutputStreamWriter:将字符流转换成字节流输出到文件,并且根据指定的编码方式转换为字节(如果不用转换流,Java会用默认编码转换为字节)
  • 默认情况下,读取文件是按照 utf-8 编码,如果文件不是 utf-8 编码,则可能出现乱码。根本问题:没有指定编码方式
  • 转换流可以完成字节流和字符流的转换,并且转换流可以指定编码类型
  • InputStreamReader 是 Reader 的子类,可以将 InputStream(字节输入流顶级父类) 转换为 Reader(字符输入流顶级父类)
  • OutputStreamWriter 是 Writer 的子类,可以将 OutputStream 转换为 Writer
  • 转换流相当于中间商,使用时将 字节流/节点流 传给 转换流 ,再将 转换流 传给 处理流 进行最终处理(也可以不用处理流,看需求),如:BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"gbk")))

常用方法

  • InputStreamReader(InputStream, Charset)
  • OutputStreamWriter(OutputStream, Charset)
  • 转换流使用的 read、write的方法,实际上还是使用的节点流的 read、write 方法

打印流:PrintStream & PrintWriter

  • 只有输出流,没有输入流

  • 可以打印到屏幕上(默认),也可以打印到文件里

  • PrintStream 是 OutputStream 的子类,是字节流

  • PrintWriter 是 Writer 的子类,是字符流

  • 注意没有 close 流,仍然不会打印到文件

  • 标准输出流 System.outPrintStream 的一个实例化对象,可以使用的方法没有区别。只是标准输出流默认(且一般)将结果打印到屏幕,PrintStream 可以选择打印到文件还是打印到屏幕。如果需要改变标准输出流输出位置,用setOut

常用方法(PrintStream 和 PrintWriter通用 )

  • 打印到某个文件时,创建对象:PrintStream out = new PrintStream("D:\\test.txt");

    若打印到屏幕则将地址换成System.out

  • print:底层用的就是 write,代码:public void print(String s) { write(String.valueOf(s));},将要print的内容转化为字符串的形式,再write出来

  • 只不过多了个 null 判断,如果为空,打印 null

  • print方法相比write方法更侧重格式化输出,不需要关心数据的类型,会自动进行类型转换

与直接使用 write 方法的区别

  • 打印流是格式化输出,可以直接打印各种类型的数据,不需要手动转换位字符串,println还会手动添加换行符,而write相比是一个更底层的方法,需要手动将数据转换为字节或字节数组
  • 打印流本身自带了缓冲输入,而write还需要配合bufferedwriter等使用才有缓冲
  • 打印流更适合文本文件写入,write更适合处理非文本数据(如二进制数据)

Properties类

  • 需求:配置文件
  • 传统方法的代码比较麻烦
  • 配置文件的格式:键=值
  • 父类是 HashTable

常用方法

  • load(Reader) 加载指定配置文件

  • list 显示k-v

  • getProperty(key) 返回的是字符串

  • setProperty(key, value) 如果该文件没有这个key,则是创建。否则是修改

  • store(Writer/OutputStream, comment)

    保存的如果是中文,则会转换成unicode码

    comment 是注释,如果为 null,则没有注释,如果写了,会在配置文件最上方写明

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

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

相关文章

代发考生战报:7月22号,广州,HCIP-Cloud Service SA云服务 H13-821考试通过

代发考生战报:7月22号,广州,HCIP-Cloud Service SA云服务 H13-821考试通过,遇到7-10个新题,剩下都是题库里的原题,记住了考试要带两个证件才行,我用的是身份证和驾照,想考的抓紧考吧…

php实现动态登录

简介: 效果:通过前端页面的注册,通过MD5将密码加密,发送到数据库,通过验证数据库的内容实现登录,以及各种保证安全的措施 实验环境:phphtmlcssmysql数据表,使用html css设计注册&a…

do语句——输入两个值求和

代码如下&#xff1a; #include<stdio.h> int main() {int sum0;int a,b;puts("请输入两个整数");printf("整数a:"); scanf("%d",&a);printf("整数b:"); scanf("%d",&b);int t(a>b)?b:a;do{sumsumt;tt1;…

PHP基于微信小程序的打车平台-计算机毕业设计源码78689

摘 要 本文介绍的是基于PHP开发的打车平台小程序。该系统旨在为用户提供一个便捷、高效的平台&#xff0c;以实现网约车的打车功能。随着社交媒体和互联网的普及&#xff0c;网约车已成为日常交通中常见的形式。然而&#xff0c;传统的打车方式存在不方便、不及时等问题。 微信…

【Kafka】对 kafka 消费程序客户端进行监控采集

前言 对于 Kafka 组件而言&#xff0c;我们通常会对 kafka 服务端添加一些监控&#xff0c;来确保服务的稳定性&#xff0c;虽然有 kafka-exporter 来对消费者进行监控&#xff0c;但是指标很少&#xff0c;对于生产者和消费者更细粒度的监控就无法做到了。只能将监控部署在客…

DDPM 核心代码解析(1)

所有代码 已上传至GitHub - duhanyue349/diffusion_model_learned_ddpm_main: 扩散模型基础框架源代码 目录结构如下 在train_cifar.py 中展示了扩散模型训练的所有代码 如果没有安装wandb 可以在create_argparser()设置 log_to_wandbFalse 一、加载模型参数 args 这里用了一…

语音转文字在线免费有什么工具?这4款工具让记录更高效

在当今职场、学术界和内容创作领域&#xff0c;人们越来越需要一种高效的方式来整理会议记录、讲座内容或采访对话。 幸运的是&#xff0c;除了传统的手动记笔记方式&#xff0c;我们还可以通过录音转文字软件来实现这一目标。这些软件能够直接将音频资料转写为文本&#xff0…

4nm点状激光模组的应用让未来科技走向潮流

在科技发展时代&#xff0c;激光技术以其高精度、高效率的特性&#xff0c;正逐步成为众多行业不可或缺的核心技术之一。其中&#xff0c;4nm点状激光模组作为激光技术领域的佼佼者&#xff0c;凭借其卓越的性能和广泛的应用前景&#xff0c;正引领着科技发展的新潮流。接下来我…

ubuntu20.04.6 安装Skywalking 10.0.1

1.前置准备 1.1. **jdk17&#xff08;Skywalking10 jdk22不兼容&#xff0c;用17版本即可&#xff09;**安装&#xff1a; https://blog.csdn.net/CsethCRM/article/details/140768670 1.2. elasticsearch安装&#xff1a; https://blog.csdn.net/CsethCRM/article/details…

Apollo:源码分析之cyber/mainboard启动入口介绍-my write, test ok

软件结构图 cyber入口 cyber的入口在"cyber/mainboard"目录中: ├── mainboard.cc // 主函数 ├── module_argument.cc // 模块输入参数 ├── module_argument.h ├── module_controller.cc // 模块加载,卸载 └── module_controller.…

Feature Corrective Transfer Learning (2024CVPR)

Feature Corrective Transfer learning Framework &#xff08;特征矫正迁移学习框架&#xff09; 旨在引导非理想图像上的模型训练与理想图像上训练的模型的特中层更紧密地对齐 Model Selection and Training on Ideal Images 首先在理想图像上训练&#xff0c;得到理想参数…

NV170D语音芯片:为洗地扫地一体机带来新体验!

随着物联网、人工智能技术的飞速发展&#xff0c;家用电器的智能化转型已成为不可逆转的趋势。在这一背景下&#xff0c;洗地扫地一体机&#xff0c;作为家务自动化的先锋&#xff0c;融合了高效清洁与便捷操作的双重优势&#xff0c;而语音芯片的应用&#xff0c;更是为其增添…

使用 nvm在linux上安装多个版本的node

使用 nvm&#xff08;Node Version Manager&#xff09;: nvm 是一个流行的 Node.js 版本管理工具&#xff0c;允许你安装和使用多个版本的 Node.js。 1、安装nvm wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash source ~/.nvm/nvm.sh2、…

javaEE(3)

目录 一. 前端浏览器保存用户信息 二. 前端路由导航守卫 三. 路由嵌套 四. web会话跟踪 1. web会话跟踪原理 2. JWT 2.1 传统的session认证 2.2 基于token的鉴权机制 2.3 jwt的构成 2.4 jwt搭建 五. 前端发送请求携带token 5.1 请求拦截器 六. 后端过滤器验证toke…

springboot合肥师范学院实习实训管理系统-计算机毕业设计源码31290

摘要 随着社会对高校毕业生的职业素养和实践能力要求不断提高&#xff0c;高校实习实训教育愈发受到重视。信息化技术的快速发展也为高校教学管理带来了新的机遇。合肥师范学院实习实训管理系统的研究就是源自当前高等教育对学生实习实训管理的需求。 实习实训管理系统充分利用…

手机录屏直播,教你3个方法,秒变录屏高手

在移动互联网飞速发展的今天&#xff0c;手机录屏直播已成为越来越多用户分享内容、交流心得的重要方式。无论是游戏高手展示高超技艺&#xff0c;还是教育从业者进行远程授课&#xff0c;手机录屏直播都能提供极大的便利。 在手机录屏的世界里&#xff0c;安卓手机和苹果手机…

深入分析 Android ContentProvider (九)

文章目录 深入分析 Android ContentProvider (九)ContentProvider 的高级使用及最佳实践&#xff08;续&#xff09;1. 复杂查询与联合查询复杂查询示例 2. 数据同步与一致性示例&#xff1a;使用事务确保数据一致性 3. 数据分页加载示例&#xff1a;分页加载数据 4. 内容提供者…

jmeter录制

1、添加代理服务器 添加方法&#xff1a;“测试计划”右键 -> 添加 -> 非测试元件 -> HTTP代理服务器 2、添加线程组 添加方法&#xff1a;“测试计划”右键->添加->线程&#xff08;用户&#xff09;->线程组 3、配置http代理服务器 &#xff08;1&a…

电脑录屏软件带声音,3款软件推荐,一键录制

在今天&#xff0c;电脑录屏软件带声音的功能已经悄然改变了我们的学习、工作和娱乐方式。录屏软件&#xff0c;这个看似简单的工具&#xff0c;实则蕴藏着无穷的魅力。它不仅能够捕捉屏幕上的每一个细节&#xff0c;还能将声音完美地融入其中。无论是游戏中的背景音乐、会议中…

谷粒商城实战笔记-77-商品服务-API-平台属性-规格参数列表

文章目录 一&#xff0c;新增product/attr/base/list接口二&#xff0c;踩坑记录1. 使用 Lazy 注解2. 使用 PostConstruct 注解代码分析解决方案分析 这一节的主要内容是完成规格参数的列表查询功能。 一&#xff0c;新增product/attr/base/list接口 这个接口用来查询规格参数…