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

文章目录

  • 文件概述
  • 常用的文件操作
    • 创建文件
    • 获取文件信息
    • 目录的操作和文件删除
    • 流的分类
    • 各抽象类常用子类对象
      • 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.mzph.cn/bicheng/51687.shtml

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

相关文章

Python | TypeError: ‘module’ object is not callable

Python | TypeError: ‘module’ object is not callable 在Python编程中,遇到“TypeError: ‘module’ object is not callable”这类错误通常表明你尝试像函数一样调用了一个模块。这种错误通常是由于导入模块时的疏忽或误解导致的。本文将深入探讨此错误的根源&…

2024年7月23日~2024年7月29日周报

目录 一、前言 二、完成情况 2.1 一种具有边缘增强特点的医学图像分割网络 2.2 融合边缘增强注意力机制和 U-Net 网络的医学图像分割 2.3 遇到的困难 三、下周计划 一、前言 上周参加了一些师兄师姐的论文讨论会议,并完成了初稿。 本周继续修改论文&#xff0…

使用eclipse在新建的java项目中编辑xml文件时Unhandled event loop exception No more handles

处理方法:更换xml编辑器 Window ——》Preferences ——》General ——》Editors ——》File Associations 如果File types里面没有*.xml,则点击Add进行新增 选中*.xml,然后在Associated editors 选中想用的编辑器,设置为defaul…

小白也能读懂的ConvLSTM!(开源pytorch代码)

ConvLSTM 1. 算法简介与应用场景2. 算法原理2.1 LSTM基础2.2 ConvLSTM原理2.2.1 ConvLSTM的结构2.2.2 卷积操作的优点 2.3 LSTM与ConvLSTM的对比分析2.4 ConvLSTM的应用 3. PyTorch代码参考文献 仅需要网络源码的可以直接跳到末尾即可 1. 算法简介与应用场景 ConvLSTM&#x…

SAPUI5基础知识22 - 图标(Icons)

1. 背景 SAPUI5 提供了一套丰富的图标库,可以用于增强应用程序的视觉吸引力和用户体验。这些图标是矢量图形,可以在任何分辨率下保持清晰,并且可以自定义颜色和大小。 2. 示例 在 SAPUI5 中,图标可以通过 sap.ui.core.Icon 控件…

Redis快速入门基础

Redis入门 Redis是一个基于内存的 key-value 结构数据库。mysql是二维表的接口数据库 优点: 基于内存存储,读写性能高 适合存储热点数据(热点商品、资讯、新闻) 企业应用广泛 官网:https://redis.io 中文网:https://www.redis.net.cn/ Redis下载与…

The Llama 3 Herd of Models 第6部分推理部分全文

第1,2,3部分 介绍,概览和预训练 第4部分 后训练 第5部分 结果 6 Inference 推理 我们研究了两种主要技术来提高Llama 3405b模型的推理效率:(1)管道并行化和(2)FP8量化。我们已经公开发布了FP8量化的实现。 6.1 Pipeline Parallelism 管道并行 当使用BF16数字表示模型参数时…

家具购物小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,家具分类管理,家具新品管理,订单管理,系统管理 微信端账号功能包括:系统首页,家具新品,家具公告&#xff0…

Linux网络——深入理解传入层协议TCP

目录 一、前导知识 1.1 TCP协议段格式 1.2 TCP全双工本质 二、三次握手 2.1 标记位 2.2 三次握手 2.3 捎带应答 2.4 标记位 RST 三、四次挥手 3.1 标记位 FIN 四、确认应答(ACK)机制 五、超时重传机制 六 TCP 流量控制 6.1 16位窗口大小 6.2 标记位 PSH 6.3 标记…

YOLOv5改进 | 卷积模块 | 无卷积步长用于低分辨率图像和小物体的新 CNN 模块SPD-Conv

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录: 《YOLOv5入门 改…

[ WARN:0@0.014] global loadsave.cpp:248 cv::findDecoder imread_

[ WARN:00.014] global loadsave.cpp:248 cv::findDecoder imread_ 目录 [ WARN:00.014] global loadsave.cpp:248 cv::findDecoder imread_ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰…

20240729 每日AI必读资讯

Meta科学家最新采访,揭秘Llama 3.1是如何炼成的 - Llama 3.1都使用了哪些数据?其中有多少合成数据?为什么不使用MoE架构?后训练与RLHF流程是如何进行的?模型评估是如何进行的? - 受访者Thomas Scialom现任…

Go语言教程(一看就会)

全篇文章 7000 字左右, 建议阅读时长 1h 以上。 Go语言是一门开源的编程语言,目的在于降低构建简单、可靠、高效软件的门槛。Go平衡了底层系统语言的能力,以及在现代语言中所见到的高级特性。它是快速的、静态类型编译语言。 第一个GO程序…

嵌入式人工智能(32-基于树莓派4B的旋转编码器-EnCoder11)

1、旋转编码器 旋转编码器是一种输入设备,通常用于测量和控制旋转运动。它由一个旋转轴和一系列编码器组成。旋转编码器可以根据旋转轴的位置和方向来测量旋转角度,并将其转化为电子信号输出。 旋转编码器通常分为两种类型:绝对值编码器和增…

嵌入式学习Day13---C语言提升

目录 一、二级指针 1.1.什么是二级指针 2.2.使用情况 2.3.二级指针与数组指针 二、指针函数 2.1.含义 2.2.格式 2.3.注意 2.4.练习 三、函数指针 3.1.含义 3.2.格式 3.3.存储 3.4.练习 ​编辑 四、void*指针 4.1.void缺省类型 4.2.void* 4.3.格式 4.4.注…

H3CNE(OSPF动态路由)

目录 7.1 静态路由的缺点与动态路由分类 7.1.1 静态路由的缺点 7.1.2 动态路由的分类 7.2 OSPF基础 7.2.1 OSPF的区域 ​编辑 7.2.2 Router-id 7.2.3 开销-Cost or Metric 7.2.4 路由转发 7.3 OSPF邻居表建立过程 7.3.1 五种包 7.3.2 建立邻居表的第一步 7.3.3 邻居建立…

模拟实现短信登录功能 (session 和 Redis 两种代码实例) 带前端演示

目录 整体流程 发送验证码 短信验证码登录、注册 校验登录状态 基于 session 实现登录 实现发送短信验证码功能 1. 前端发送请求 2. 后端处理请求 3. 演示 实现登录功能 1. 前端发送请求 2. 后端处理请求 校验登录状态 1. 登录拦截器 2. 注册拦截器 3. 登录完整…

RocketMQ事务消息机制原理

RocketMQ工作流程 在RocketMQ当中,当消息的生产者将消息生产完成之后,并不会直接将生产好的消息直接投递给消费者,而是先将消息投递个中间的服务,通过这个服务来协调RocketMQ中生产者与消费者之间的消费速度。 那么生产者是如何…

昇思25天学习打卡营第19天|DCGAN生成漫画头像

DCGAN生成漫画头像总结 实验概述 本实验旨在利用深度卷积生成对抗网络(DCGAN)生成动漫头像,通过设置网络、优化器以及损失函数,使用MindSpore进行实现。 实验目的 学习和掌握DCGAN的基本原理和应用。熟悉使用MindSpore进行图像…

网络协议一 : 搭建tomacat,intellij IDEA Ultimate 的下载,安装,配置,启动, 访问

需要搭建的环境 1.客户端--服务器开发环境 客户端:浏览器(HTMLCSSJS) 服务器:JAVA 1.安装JDK,配置JAVA_HOME 和 PATH 2.安装Tomcat 3.安装IDE--intellij IDEA Ultimate 是旗舰版的意思。 2.TOMCAT 的下载和解…