【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,一经查实,立即删除!

相关文章

LeetCode 算法:搜索插入位置 c++

原题链接🔗:搜索插入位置 难度:简单⭐️ 题目 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(l…

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…

vivado LOC

LOC LOC指定逻辑单元对目标SITE资源的放置分配 Xilinx部分。 LOC属性或约束有时与BEL属性一起使用,以定义精确的 将细胞放置在设备内。在这些情况下,必须定义BEL约束 否则将发生放置错误。 提示:要将I/O端口分配给设备包上的物理引脚&#xf…

大语言模型系列——Transformer 介绍与使用

引言 自从 Google 在 2017 年发表了一篇题为《Attention Is All You Need》的论文以来,Transformer 已经成为了自然语言处理领域的一个重要里程碑。与传统的 RNN 和 LSTM 不同,Transformer 通过自注意力机制(Self-Attention Mechanism&#…

使用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…

Selenium---Xpath选择器

XPath (XML Path Language) 是由国际标准化组织W3C指定的,用来在 XML 和 HTML 文档中选择节点的语言。 xpath 语法中,整个HTML文档根节点用/表示,如果我们想选择的是根节点下面的html节点,则可以在搜索框输入 /html如果输入下面…

vpp中的不同节点的数据传输,使用vpp中的回调函数,相同的原理也可以实现,不同节点的函数的调用

vpp中的不同节点的数据传输,使用vpp中的回调函数,相同的原理也可以实现,不同节点的函数的调用 1.实现数据传输所需要用到的函数2.具体实现 1.实现数据传输所需要用到的函数 需要用到的一个宏__clib_export 作用:就是将这后边的…

小白也能读懂的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…

app-routing.module.ts 简单介绍

Angular的路由是一种功能,它允许应用程序响应不同的URL路径或参数并根据这些路径加载不同的组件。app-routing.module.ts是Angular项目中负责设置应用程序路由的文件。 以下是一个简单的app-routing.module.ts文件示例,它配置了三个路由: i…

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下载与…

Spring缓存注解

Spring缓存注解 EnableCaching | 来启动缓存注解Cached | 用来表示某一个方法的结果可以被缓存 Cached(name “testCache:id1:”, key “#testId”, cacheType CacheType.REMOTE, localLimit CustomerConstants.DEFAULT_LIMIT, expire 1800)方法方法上。 #相关参数&#…

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…

【开发学习笔记】git的工作区与分支

Git是一款分布式版本控制系统,被广泛应用于软件开发中,用于跟踪和管理项目的源代码。在Git中,工作区与分支是两个核心概念,它们在Git的工作流程中扮演着不同的角色。 工作区的概念 工作区(Working Directory&#xf…

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现任…