Java SE 学习笔记(十四)—— IO流(2)

目录

  • 1 字节流
    • 1.1 字节流写数据
      • 1.1.1 创建字节输出流对象
      • 1.1.2 字节流写数据
    • 1.2 字节流读数据
      • 1.2.1 创建字节输入流对象
      • 1.2.2 字节流读数据
    • 1.3 字节流复制文件
    • 1.4 流的刷新与关闭
    • 1.5 资源释放方式
      • 1.5.1 try-catch-finally
      • 1.5.2 try-with-resource
  • 2 字符流
    • 2.1 字符流概述
    • 2.2 字符流写数据
    • 2.3 字符流读数据

1 字节流

1.1 字节流写数据

1.1.1 创建字节输出流对象


  • 字节流抽象基类
    • InputStream:这个抽象类是表示字节输入流的所有类的超类
    • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    • 子类名特点:子类名称都是以其父类名作为子类名的后缀
  • 字节输出流
    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件
  • 使用字节输出流写数据的步骤
    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法
    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

在这里插入图片描述

示例代码:

public static void main(String[] args) throws IOException {//1.创建字节输出流的对象FileOutputStream fos = new FileOutputStream("D:\\a.txt");//FileOutputStream fos = new FileOutputStream(new File("D:\\a.txt"));

注意:

  • 如果文件不存在,会帮我们自动创建出来.
  • 如果文件存在,会把文件清空.

1.1.2 字节流写数据


在这里插入图片描述

示例代码:

public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");/*fos.write(97);fos.write(98);fos.write(99);*//* byte[] bys = {97,98,99};fos.write(bys);*/byte [] bys = {97,98,99,100,101,102,103};fos.write(bys,1,2); //98,99即写入bcfos.close();
}

那么,现在有两个小问题

  • 字节流写数据如何实现换行?
    • windows:\r\n
    • linux:\n
    • mac:\r
    • getBytes()是字符串的一个方法,可以将字符串转换为字节
  • 字节流写数据如何实现追加写入?
    • public FileOutputStream(String name,boolean append)
    • 创建文件输出流对象以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头

示例代码:

public static void main(String[] args) throws IOException {//第二个参数就是续写开关,如果没有传递,默认就是false,//表示不打开续写功能,那么创建对象的这行代码会清空文件.//如果第二个参数为true,表示打开续写功能//那么创建对象的这行代码不会清空文件.FileOutputStream fos = new FileOutputStream("bytestream\\a.txt",true);fos.write(97);//加一个换行fos.write("\r\n".getBytes());fos.write(98);//加一个换行fos.write("\r\n".getBytes());fos.write(99);//加一个换行fos.write("\r\n".getBytes());fos.write(100);//加一个换行fos.write("\r\n".getBytes());fos.write(101);//加一个换行fos.write("\r\n".getBytes());fos.close();
}

1.2 字节流读数据

1.2.1 创建字节输入流对象


字节输入流

  • FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

在这里插入图片描述

1.2.2 字节流读数据


在这里插入图片描述

字节输入流读取数据的步骤:

  • 创建字节输入流对象
  • 调用字节输入流对象的读数据方法
  • 释放资源

1. 一次读一个字节数据

public static void main(String[] args) throws IOException {//如果文件存在,那么就不会报错.//如果文件不存在,那么就直接报错.FileInputStream fis = new FileInputStream("bytestream\\a.txt");int read = fis.read();//一次读取一个字节,返回值就是本次读到的那个字节数据.//也就是字符在码表中对应的那个数字.//如果我们想要看到的是字符数据,那么一定要强转成charSystem.out.println(read); // 97System.out.println((char)read); //a//释放资源fis.close();
}

改进:使用循环

public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("bytestream\\a.txt");//文件中多个字节我怎么办?/*while(true){int i1 = fis.read(); 内容读取结束读取到空格时返回-1System.out.println(i1); }*/ int b;while ((b = fis.read())!=-1){System.out.println((char) b);}fis.close();
}

每个读取一个字节存在什么问题呢?

  • 性能较慢
  • 读取中文字符输出无法避免乱码问题

2. 一次读一个字节数组

一次读一个字节数组的方法:

  • public int read(byte[] b):从输入流读取最多b.length个字节的数据
  • 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数

注意:

  • hello.txt文件内容为:ab3abccd
  • io为当前模块名
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("io/src/hello.txt");byte[] bytes = new byte[3];int len1 = fis.read(bytes);System.out.println("读取了" + len1 + "字节"); // 读取了3字节String s1 = new String(bytes);System.out.println(s1); // ab3int len2 = fis.read(bytes);System.out.println("读取了" + len2 + "字节"); // 读取了3字节String s2 = new String(bytes);System.out.println(s2); // abcint len3 = fis.read(bytes);System.out.println("读取了" + len3 + "字节"); // 读取了2字节
//        String s3 = new String(bytes);
//        System.out.println(s3); // cdc
//        注意:上一次读取的是abc,这一次由于只读两个,所以只会覆盖前两个字符// 读多少倒出多少String s3 = new String(bytes, 0, 2);System.out.println(s3); // cd
}

每次读取一个字节数组存在什么问题?

  • 读取的性能得到了提升
  • 读取中文字符输出无法避免乱码问题。

3. 一次读完全部字节

(1)定义一个与文件一样大的字节数组byte[] bytes=new byte[(int) f.length()],一次性读完文件的全部字节,这样直接把文件数组全部读取到一个字节数组里可以避免乱码,但是如果文件过大,字节数组可能会引起内存溢出。

(2)官方为字节输入流 InputStream 提供了如下 API 可以直接把文件的全部数据读取到一个字节数组中

在这里插入图片描述

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;public class Test {public static void main(String[] args) throws IOException {File f = new File("io/src/hello.txt");FileInputStream fis = new FileInputStream(f);// 方法一
//        byte[] bytes = new byte[(int) f.length()];
//        int len = fis.read(bytes);
//        System.out.println("读取了" + len + "字节"); // 读取了8字节
//        System.out.println("文件的大小:" + f.length()+"字节"); // 文件的大小:8字节
//        System.out.println(new String(bytes)); // ab3abccd// 方法二byte[] bytes1 = fis.readAllBytes();System.out.println(new String(bytes1)); // ab3abccd}
}

1.3 字节流复制文件


  1. 小文件复制

C:\it\a.jpg的文件复制到模块 bytestream 下

public static void main(String[] args) throws IOException {//创建了字节输入流,准备读数据.FileInputStream fis = new FileInputStream("C:\\test\\a.jpg");//创建了字节输出流,准备写数据.FileOutputStream fos = new FileOutputStream("bytestream\\a.jpg");int b;while((b = fis.read())!=-1){fos.write(b);}fis.close();fos.close();
}
  1. 大文件复制

对于大文件的复制问题,字节流通过创建字节数组,可以一次读写多个数据

public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("C:\\test\\a.avi");FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");byte [] bytes = new byte[1024];// 该字节数组的大小是1024字节int len;//本次读到的有效字节个数 --- 这次读了几个字节while((len = fis.read(bytes))!=-1){  // 循环读取fos.write(bytes,0,len);//0索引开始,读取len个字节}fis.close();fos.close();
}

字节流适合做一切文件数据的拷贝吗?

  • 任何文件的底层都是字节,拷贝是一字不漏的转移字节,只要前后文件格式,编码一致就没有任何问题。

1.4 流的刷新与关闭


以下两种方法能够让写出去的数据成功生效

在这里插入图片描述

1.5 资源释放方式

1.5.1 try-catch-finally


有如下代码:

try {FileOutputStream fos = new FileOutputStream("a.txt");fos.write(97);fos.close();
}catch (IOException e){e.printStackTrace();
}

我们如何操作才能让close方法一定执行呢?

异常处理的标准格式:

try{可能出现异常的代码;
}catch(异常类名 变量名){异常的处理代码;
}finally{执行所有清除操作; // 在异常处理时提供finally块来执行所有的清除操作,比如IO流的释放资源,被finally控制的语句一定会执行,除非JVM退出
}

加异常处理后的代码如下:

public static void main(String[] args) {FileOutputStream fos = null;try {//System.out.println(2/0);fos = new FileOutputStream("D:\\a.txt");//FileOutputStream fos = new FileOutputStream("D:\\a.txt");//此时fos是局部变量,在finally里无法执行fos.close();fos.write(97);}catch(IOException e){e.printStackTrace();}finally {//finally语句里面的代码,一定会被执行.if(fos != null){//如果fos为null就不会和上述路径的文件产生关系,就不用关闭文件try {fos.close();} catch (IOException e) {e.printStackTrace();}}}
}

finally 虽然可以用于释放资源,但是释放资源的代码过于繁琐

1.5.2 try-with-resource


在这里插入图片描述

JDK 7 以及 JDK 9 的 ()只能 放置资源对象,用完会自动关闭,自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)

  • 什么是资源呢?
    • 资源都是实现了 Closeable/AutoCloseable 接口的类对象

在这里插入图片描述

2 字符流

2.1 字符流概述


既然字节流可以操作所有文件,为什么要学习字符流?

  • 如果利用字节流,把文本文件中的中文,读取到内存中,有可能出现乱码
  • 如果利用字节流,把中文写到文本文件中,也有可能出现乱码

为什么字节流读取文本文件,可能会出现乱码?

  • 因为字节流一次读一个字节,而不管GBK还是UTF-8一个中文都是多个字节,用字节流每次只能读其中的一部分,所以会出现乱码的问题

由于字节流操作中文不是特别的方便,所以Java就提供字符流(字符流 = 字节流 + 编码表)。字符流更适合操作中文,最小单位就是按照单个字符读写的。

2.2 字符流写数据


Writer: 用于写入字符流的抽象父类
FileWriter: 用于写入字符流的常用子类

构造方法:

在这里插入图片描述

成员方法:

在这里插入图片描述

public static void main(String[] args) throws IOException {//创建字符输出流的对象//FileWriter fw = new FileWriter(new File("charstream\\a.txt"));FileWriter fw = new FileWriter("charstream\\a.txt");//写一个字符fw.write(97);fw.write(98);fw.write(99);//写出一个字符数组char [] chars1 = {97,98,99,100,101};fw.write(chars1);//写出字符数组的一部分char [] chars2 = {97,98,99,100,101};fw.write(chars2,0,3);//写一个字符串String line1 = "黑马程序员abc";fw.write(line1);//写一个字符串的一部分String line2 = "黑马程序员abc";fw.write(line2, 0, 2);//释放资源fw.close();
}

注意:

  • 在创建字符输出流对象时,如果文件存在就清空,如果文件不存在就创建,但是要保证父级路径存在
  • 写数据时,写出int类型的整数,实际写出的是整数在码表上对应的字母,写出字符串数据,是把字符串本身原样输出

2.3 字符流读数据


Reader: 用于读取字符流的抽象父类
FileReader: 用于读取字符流的常用子类

构造方法

在这里插入图片描述
成员方法

在这里插入图片描述

public static void main(String[] args) throws IOException {//创建字符输入流的对象// FileReader fr = new FileReader(new File("charstream\\a.txt"));FileReader fr = new FileReader("charstream\\a.txt");//读取数据//一次读取一个字符
/*        int ch;while((ch = fr.read()) != -1){System.out.println((char) ch);}*///一次读取多个字符。//创建一个数组char [] chars = new char[1024];int len;//read方法还是读取,但是是一次读取多个字符//他把读到的字符都存入到chars数组。//返回值:表示本次读到了多少个字符。while((len = fr.read(chars))!=-1){System.out.println(new String(chars,0,len));}//释放资源fr.close();
}

小结:

  • 字节流适合做一切文件的拷贝
  • 字符流适合做文本文件的操作(读写)
    • 想要把文本文件中的数据读到内存中,使用字符输入流
    • 想要把内存中的数据写到文本文件中,使用字符输出流

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

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

相关文章

C#__简单了解XML文档

/* XML(可扩展标记语言):用于传输和存储数据 XML文档:树结构;包含根元素 XML元素:从开始标签到结束标签的部分 XML语法规则: 1、所有XML元素都必须有结束标签 …

微信小程序vue+uniapp旅游景点门票预订系统 名胜风景推荐系统

与此同时越来越多的旅游公司建立了自己的基于微信小程序的名胜风景推荐平台,管理员通过网站可以添加用户、景点分类、景点信息、在线预订、最新推荐,用户可以对景点信息进行在线预订,以及开展电子商务等。互联网的世界里蕴藏无限生机&#xf…

仓库管理系统源代码集合,带图片展示和网站演示

目录 1、ModernWMS2、GreaterWMS3、kopSoftWMS4、SwebWMS5、若依wms6、jeewms 1、ModernWMS 体验地址:https://wmsonline.ikeyly.com 简易完整的仓库管理系统 该库存管理系统是,我们从多年ERP系统研发中总结出来的一套针对小型物流仓储供应链流程。 简…

Spring cloud教程Gateway服务网关

Spring cloud教程|Gateway服务网关 写在前面的话: 本笔记在参考网上视频以及博客的基础上,只做个人学习笔记,如有侵权,请联系删除,谢谢! Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,…

【vtk学习笔记1】编译安装vtk9.2.6,运行官方例子

一、编译安装vtk-9.2.6 1. 下载VTK。推荐从github下载。目前从VTK官网只能下载最新的RC版或者以前的老版本,我是在github上下载的vtk9.2.6 tag版本。 2. 用Cmake-gui配置Visual Studio工程。主要注意配置VTK安装的路径、是否支持QT,需要的话正确配置Qt5…

JavaWeb 怎么在servlet向页面输出Html元素?

service()方法里面的方法体&#xff1a; resp.setContentType("text/html;charsetutf-8");//获得输出流PrintWriter对象PrintWriter outresp.getWriter();out.println("<html>");out.println("<head><title>a servlet</title>…

python自动化测试(六):唯品会商品搜索-练习

目录 一、配置代码 二、操作 2.1 输入框“运动鞋” 2.2 点击搜索按钮 2.3 选择品牌 2.4 选择主款 2.5 适用性别 2.6 选择尺码 2.7 选择商品&#xff1a;&#xff08;通过css的属性去匹配&#xff09; 2.8 点击配送地址选项框 一、配置代码 # codingutf-8 from selen…

RPA除了和OCR、NLP技术结合,还能和什么技术结合?

鉴于业内现在也经常把RPA称为数字员工&#xff0c;就虚拟一个人的形象来解答吧。 首先是头部&#xff0c;实现人的“听看说想”能力&#xff1a; 听&#xff1a;ASR&#xff08;语音识别技术&#xff09;&#xff0c;主要用于听取和理解语音输入&#xff0c;让RPA能处理语音数…

大数据Flink(一百零三):SQL 表值聚合函数(Table Aggregate Function)

文章目录 SQL 表值聚合函数(Table Aggregate Function) SQL 表值聚合函数(Table Aggregate Function) Python UDTAF,即 Python TableAggregateFunction。Python UDTAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等,与…

leetcode经典面试150题---4.删除有序数组中的重复项II

目录 题目描述 前置知识 代码 方法一 双指针 思路 图解 实现 复杂度 题目描述 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&…

泰州市旅游景点门票预订管理系统 vue+uniapp微信小程序

本文从管理员、用户的功能要求出发&#xff0c;泰州市旅游景点管理小程序中的功能模块主要是实现用户、景点类型、景区信息、门票预定。经过认真细致的研究&#xff0c;精心准备和规划&#xff0c;最后测试成功&#xff0c;系统可以正常使用。分析功能调整与泰州市旅游景点管理…

java代码审计-不安全的配置-Tomcat任意文件写入(CVE-2017-12615)

Tomcat任意文件写入&#xff08;CVE-2017-12615&#xff09; 影响范围&#xff1a;Apache Tomcat 7.0.0 - 7.0.79 (windows环境) 当 Tomcat 运行在 Windows 操作系统时&#xff0c;且启用了 HTTP PUT 请求方法&#xff08;例如&#xff0c;将 readonly 初始化参数由默认值设置…

centos7 部署 Flink

1. 准备 安装的前提是虚拟机里已安装了jdk 去官网下载 Flink 所有版本下载地址&#xff1a;https://archive.apache.org/dist/flink/ 找到下图的安装包&#xff0c;下载即可 下载完后&#xff0c;将其上传至虚拟机的某个地方&#xff0c;本人将其放在 /home/flink/ 下 解压…

帮你快速解锁忘记密码手机的十个工具

将手机解锁到任时候都会让人感觉呼吸新鲜空气。这就像摆脱无形的锁链一样&#xff0c;让您有权选择并避免那些讨厌的限制。但如何解锁手机呢&#xff1f;这就是解锁软件发挥作用的地方。这些方便的工具可以帮助您摆脱束缚并打开一个充满可能性的世界。 解锁手机的合法性 现在&…

分布式理论和分布式锁知识点总结

文章目录 (一) 分布式理论算法和协议1&#xff09;CAP理论总结 2&#xff09;BASE理论BASE 理论的核心思想基本可用软状态最终一致性 3&#xff09;Paxos算法Basic Paxos 算法4&#xff09; Raft算法1 拜占庭将军 5&#xff09;Gossip协议 (二) 分布式锁分布式锁应该具备哪些条…

关于数据中台的理解和思考

一、什么是数据中台 数据中台是指通过数据技术&#xff0c;对海量数据进行采集、计算、存储、加工&#xff0c;同时统一标准和口径。把数据统一后&#xff0c;会形成标准数据&#xff0c;再进行存储&#xff0c;形成大数据资产层&#xff0c;进而为客户提供高效的、可复用的服…

心血管疾病药物不良反应不容忽视,华大基因基因检测辅助降低风险!

随着医疗技术的不断进步&#xff0c;个体化用药已经成为药物治疗的新趋势。在此趋势下&#xff0c;华大基因基因检测基于药物基因组学的药物选择和个性化用药方案&#xff0c;为心血管疾病患者的临床治疗提供了新机会&#xff0c;同时可以更好地帮助患者控制心血管疾病&#xf…

【精选】VMware部署ESXI6.5 vCenter Server详解

VMware部署ESXI6.5 vCenter Server 一、ESXi主机介绍1、虚拟机的好处2、为什么要使用虚拟机 二、虚拟化服务器概述1、VSphere物理架构2、体系架构3、VMware vSphere 组件 三、ESXi安装环境1、安装步骤2、使用VMware新建ESXi主机3、初始环境安装 四、创建虚拟机五、安装部署VMwa…

数据结构OJ题

目录 1.字符串左旋 2.字符串旋转结果 3.旋转数组 4.移除元素 本篇主要是讲解一些OJ题目。 1.字符串左旋 字符串左旋 实现一个函数&#xff0c;可以左旋字符串中的k个字符 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 方法1【暴力求解】 翻转1…

[hadoop全分布部署]安装Hadoop、配置Hadoop 配置文件②

&#x1f468;‍&#x1f393;&#x1f468;‍&#x1f393;博主&#xff1a;发量不足 个人简介&#xff1a;耐心&#xff0c;自信来源于你强大的思想和知识基础&#xff01;&#xff01; &#x1f4d1;&#x1f4d1;本期更新内容&#xff1a;安装Hadoop、配置Hadoop 配置文件…