JAVA进阶学习13

文章目录

      • 2.2.3 综合输入和输出方法进行文件拷贝
      • 2.2.4 字节流读取时乱码的问题
    • 2.3 字符流的方法概述
      • 2.3.1 FileReader方法
      • 2.3.2 FileWriter方法
      • 2.3.3 小结
  • 三、高级IO流
    • 3.1 缓冲流
      • 3.1.1 字节缓冲流
      • 3.1.2 字符缓冲流
    • 3.2 转换流
    • 3.3 序列化流
      • 3.3.1 序列化流
      • 3.3.2 反序列化流
    • 3.4 打印流
      • 3.4.1 字节打印流
      • 3.4.2 字符打印流
    • 3.5 压缩流
      • 3.5.1 解压流
      • 3.5.2 压缩流
      • 3.5.3 将文件夹转换为压缩包

本文接上篇 进阶12所写,继续学习IO流

2.2.3 综合输入和输出方法进行文件拷贝

public static void main(String[] args) {/** 利用try...catch...finally捕获拷贝文件中代码出现的异常*///1.创建对象FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("D:\\itheima\\movie.mp4");fos = new FileOutputStream("myio\\copy.mp4");//2.拷贝int len;byte[] bytes = new byte[1024 * 1024 * 5];//5M每次的存取while((len = fis.read(bytes)) != -1){fos.write(bytes,0,len);}} catch (IOException e) {//e.printStackTrace();} finally {//3.释放资源if(fos != null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}if(fis != null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
  • 在代码中做了对异常的基本处理,不再是一般的抛出形式
  • 此处不管运行过程中代码是否出现异常都需要资源的释放,固应该将资源释放部分放在finally中执行
  • 在JAVA的后期版本中有资源自动释放的接口AutoCloseable,可避免麻烦的处理

2.2.4 字节流读取时乱码的问题

字符集概述

  1. 计算机中的字符存储单位是字节
  2. 最简单的字符集是ASCII字符集,每个字符占一个字节
    • 高位以0开头
  3. 早期我国针对汉字和日文韩文推出了GBK字符集
    • GBK字符集是完全兼容ASCII字符集的
    • 每个字符占两个字节,告位以1开头
  4. 在Uncode字符集中(万国码),包含了大多国家的文字
    • 针对该字符集有多种编码方式,最为常见的就是UTF-8编码方式
    • 在Unicode字符集的UTF-8编码时,汉字用三个字节进行存储

由上面的描述不难看出,在文件读取时出现乱码的肯能原因主要有:

  1. 一次读取一个字节的文件信息,并没有完全读取一个字符
  2. 在写文件和读文件时的编码方式不相同

由以下的字符串案例进行展示

public static void main(String[] args) throws UnsupportedEncodingException {/*以下的字符串函数Java中编码的方法public byte[] getBytes()                        使用默认方式进行编码public byte[] getBytes(String charsetName)      使用指定方式进行编码Java中解码的方法String(byte[] bytes)                            使用默认方式进行解码String(byte[] bytes, String charsetName)        使用指定方式进行解码*///1.编码String str = "我爱学JAVA";byte[] bytes1 = str.getBytes();System.out.println(Arrays.toString(bytes1));byte[] bytes2 = str.getBytes("GBK");System.out.println(Arrays.toString(bytes2));//2.解码String str2 = new String(bytes1);System.out.println(str2);String str3 = new String(bytes1,"GBK");System.out.println(str3);}

2.3 字符流的方法概述

在这里插入图片描述

2.3.1 FileReader方法

在这里插入图片描述

public static void main(String[] args) throws IOException {/*第一步:创建对象public FileReader(File file)        创建字符输入流关联本地文件public FileReader(String pathname)  创建字符输入流关联本地文件第二步:读取数据public int read()                   读取数据,读到末尾返回-1public int read(char[] buffer)      读取多个数据,读到末尾返回-1第三步:释放资源public void close()                 释放资源/关流*///1.创建对象并关联本地文件FileReader fr = new FileReader("myio\\a.txt");//2.读取数据 read()//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节int ch;while((ch = fr.read()) != -1){System.out.print((char)ch);//用类型强制转换可以将十进制数转换成对应的中文字符}//3.释放资源fr.close();}

运行时的细节:

  1. read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
  2. 在读取之后,方法的底层还会进行解码并转成十进制,并返回十进制数
    这个十进制的数据也表示在字符集上的数字
    英文:文件里面二进制数据 0110 0001
    read方法进行读取,解码并转成十进制97
    中文:文件里面的二进制数据 11100110 10110001 10001001
    read方法进行读取,解码并转成十进制27721

对于字符流的read方法在底层中是存在一个缓冲区的

  • 当首次运行read方法,系统会读取文件,试图将这个数组类型的缓冲区装满
  • 每次read就从缓冲区中取出一个字符的数据
  • 当缓冲区全部读完后,由会第二次打开文件将剩余的内容再次读入到缓冲区中

2.3.2 FileWriter方法

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


在fileWriter中也存在着缓冲区每次书写并不是直接写入到文件中而是先写在缓冲区中

2.3.3 小结

字符流不同于字节流在读写的时候是以字符为单位的,所有有必要为他们设置一个缓冲区,将原本的字节信息放入到缓冲区中再进行编码操作在进行下一步的处。
字节流:字节信息–>处理
字符流:字节信息–>编码–>处理

三、高级IO流

高级的IO流是主要是对普通文件流的包装使之具有一定的特性

3.1 缓冲流

在普通IO流的基础上加入缓冲区

在这里插入图片描述

3.1.1 字节缓冲流

在这里插入图片描述
该类是在基本流的基础上创建的

public static void main(String[] args) throws IOException {//1.创建缓冲流的对象BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myio\\a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\copy.txt"));//2.循环读取并写到目的地int b;//byte[] buytes= new byte[10]//while ((b = bis.read(bytes)) != -1) {每次多字节读取while ((b = bis.read()) != -1) {bos.write(b);}//3.释放资源bos.close();bis.close();}

加快读取速度的原理
在这里插入图片描述
每次读取在缓冲区中最多读取8192个字节,通过变量b进行转存,避免了每次读取的磁盘访问,而将操作全部转移至内存中进行。

3.1.2 字符缓冲流

构造方法
在这里插入图片描述
同字节缓冲流
字符缓冲流的特殊方法
在这里插入图片描述
注意

  • readline方法在读取时不会读入换行符
  • newline方法为了实现跨平台书写换行符,因为不同的操作系统文件的换行符不一致

缓冲流总结

  • 缓冲流在输出流中要实现续写,应该将续写布尔值写在被包装类
  • 字节缓冲流与字符缓冲流的缓冲区类型和大小不一致,一个是字节(byte)为单位,一个是字符(char)为单位

3.2 转换流

是字节流和字符流之间的转换桥梁,可以让字节流在存储时具有字符流的特性(根据字符集不同一次读取多个字节,读取数据时不会乱码)

在这里插入图片描述
注意:在命名时前半部分是字节流命名,后半部分是字符流命名
且转换流本身就是一种字符流,也可以使用字符流的方法

文件类型转换代码示例

public static void main(String[] args) throws IOException {/*将本地文件中的GBK文件,转成UTF-8*////1.JDK11以前的方案InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\b.txt"),"GBK");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\d.txt"),"UTF-8");int b;while((b = isr.read()) != -1){osw.write(b);}osw.close();isr.close();//2.替代方案FileReader fr = new FileReader("myio\\b.txt", Charset.forName("GBK"));FileWriter fw = new FileWriter("myio\\e.txt",Charset.forName("UTF-8"));int b;while ((b = fr.read()) != -1){fw.write(b);}fw.close();fr.close();}
public static void main(String[] args) throws IOException {/*利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码//1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定//2.字节流里面是没有读一整行的方法的,只有字符缓冲流才能搞定*/BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("myio\\a.txt")));String line;while ((line = br.readLine()) != null){System.out.println(line);}br.close();}

总结:当字节流中需要使用到字符流的方法时需要引入转换流作为中间的桥梁

3.3 序列化流

序列化流为了将对象存储在文件当中,防止恶意的修改等事件的发生
它是字节流的高级流

3.3.1 序列化流

public static void main(String[] args) throws IOException {/*构造方法:public ObjectOutputStream(OutputStream out)         把基本流变成高级流成员方法:public final void writeObject(Object obj)           把对象序列化(写出)到文件中去*///1.创建对象Student stu = new Student("zhangsan",23);//2.创建序列化流的对象/对象操作输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));//3.写出数据oos.writeObject(stu);//4.释放资源oos.close();}

注意:序列化存储对象之前要将对象实现Serializable接口

3.3.2 反序列化流

public static void main(String[] args) throws IOException, ClassNotFoundException {/*构造方法:public ObjectInputStream(InputStream out)         把基本流变成高级流成员方法:public Object readObject()                        把序列化到本地文件中的对象,读取到程序中来*///1.创建反序列化流的对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myio\\a.txt"));//2.读取数据Student o = (Student) ois.readObject();//3.打印对象System.out.println(o);//4.释放资源ois.close();}

注意:如果多个对象需要读取,每次ois.readObject()读取一个对象

ArrayList<Student> list =(ArryList<Student>) ois.readObject();for(Student stu : list){System.out.println(stu);
}

3.4 打印流

打印流不能读只能写,并且可以支持数据的原样写出

3.4.1 字节打印流

基本的构造方法
在这里插入图片描述
加上自动刷新可以边打印边查看
成员方法
在这里插入图片描述
数据原样写出:是指数据在写入文件时不会将数据转为对应的ASCII写入文件,而是将形参中传递的变量原封不动地直接写入文件
代码举例

public static void main(String[] args) throws FileNotFoundException {//1.创建字节打印流的对象PrintStream ps = new PrintStream(new FileOutputStream("进阶13附加//a.txt"), true, Charset.forName("UTF-8"));//2.写出数据ps.println(97);//写出 + 自动刷新 + 自动换行 直接写入97ps.print(true); //直接没写入trueps.println();ps.printf("%s爱上了%s","阿珍","阿强");//3.释放资源ps.close();}

3.4.2 字符打印流

构造方法
在这里插入图片描述
常用第三个构造方法
成员方法
与字节打印流的成员方法一致


在平时我们最常用的System.out.println()就是一种打印流
System.out就是获取打印流对象,只不过这个对象由虚拟机自动初始化
println便是打印流方法,将传入的参数打印在终端界面上
在使用后一般不会关闭该系统打印流(标准打印流),否则需要重启虚拟机以再次开启该流

3.5 压缩流

在这里插入图片描述

压缩流是字节流的子类解压的过程是读,压缩的过程是写

3.5.1 解压流

压缩包中每个文件是一个zipentry对象,解压时就是将该对象转化为原本的类型并存在一个指定的文件夹中

public static void unzip(File src,File dest) throws IOException {//解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地中//创建一个解压缩流用来读取压缩包中的数据ZipInputStream zip = new ZipInputStream(new FileInputStream(src));//要先获取到压缩包里面的每一个zipentry对象//用压缩流来获取压缩包中的对象,并将它转为原文件ZipEntry entry;while((entry = zip.getNextEntry()) != null){System.out.println(entry);//entry对象中不仅包含着当前的文件名称,还有它完整的路径,如aaa/bbb.txtif(entry.isDirectory()){//文件夹:需要在目的地dest处创建一个同样的文件夹File file = new File(dest,entry.toString());file.mkdirs();}else{//文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));int b;while((b = zip.read()) != -1){//写到目的地fos.write(b);}fos.close();//表示在压缩包中的一个文件处理完毕了。zip.closeEntry();}}zip.close();}

3.5.2 压缩流

  public static void toZip(File src,File dest) throws IOException {//1.创建压缩流关联压缩包,在其内部中为一个压缩包的文件路径ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));//2.创建压缩包中的内容->创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹//参数:压缩包里面的路径ZipEntry entry = new ZipEntry("aaa\\bbb\\a.txt");//3.把ZipEntry对象放到压缩包当中zos.putNextEntry(entry);//4.把src文件中的数据写到压缩包的对象中//创建输入流读取源文件中字节,用来向内写入数据FileInputStream fis = new FileInputStream(src);int b;while((b = fis.read()) != -1){zos.write(b);//向entry中写入数据}zos.closeEntry();zos.close();}

总结:该过程整体分为两步

  1. 首先是获取压缩包的相关流
  2. 创建压缩包对象用来接收或向压缩包输入文件

3.5.3 将文件夹转换为压缩包

public static void main(String[] args) throws IOException {//1.创建File对象表示要压缩的文件夹File src = new File("D:\\aaa");//2.创建File对象表示压缩包放在哪里(压缩包的父级路径)File destParent = src.getParentFile();//D:\\//3.创建File对象表示压缩包的路径File dest = new File(destParent,src.getName() + ".zip");//4.创建压缩流关联压缩包ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));//5.获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中toZip(src,zos,src.getName());//aaa//6.释放资源zos.close();}public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {//1.进入src文件夹File[] files = src.listFiles();//2.遍历数组for (File file : files) {if(file.isFile()){//3.判断-文件,变成ZipEntry对象,放入到压缩包当中//此处不能用files.toString()的方法,该方法获取的是绝对路径//故采用文件名逐级增加的方式ZipEntry entry = new ZipEntry(name + "\\" + file.getName());//aaa\\no1\\a.txtzos.putNextEntry(entry);//读取文件中的数据,写到压缩包FileInputStream fis = new FileInputStream(file);int b;while((b = fis.read()) != -1){zos.write(b);}fis.close();zos.closeEntry();}else{//4.判断-文件夹,递归toZip(file,zos,name + "\\" + file.getName());//     no1        aaa   \\   no1}}}

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

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

相关文章

极简聊天室-websocket版

再写一个极简聊天室的websocket版&#xff0c;在本例中&#xff0c;websocket仅用于服务器向客户端传输信息&#xff0c;客户端向服务器发送信息是传统的http post方式&#xff0c;用axios来实现的&#xff0c;当然websocket本身是支持双向通信&#xff0c;主要是为了方便跟前面…

【leetcode详解】正方形中的最多点数【中等】(C++思路精析)

思路精析&#xff1a; 自定义结构体解读&#xff1a; 一个点是否在题给正方形中&#xff0c;只取决于其横纵坐标的最大值&#xff0c;记为dis 沟通二位数组points和字符串s的桥梁&#xff0c;就是这个点的序号&#xff0c;记为idx 由此自定义结构体&#xff0c;储存dis 和i…

基于 KubeSphere 的 Kubernetes 生产环境部署架构设计及成本分析

转载&#xff1a;基于 KubeSphere 的 Kubernetes 生产环境部署架构设计及成本分析 前言 导图 1. 简介 1.1 架构概要说明 今天分享一个实际小规模生产环境部署架构设计的案例&#xff0c;该架构设计概要说明如下&#xff1a; 本架构设计适用于中小规模(<50)的 Kubernetes …

C#对象和类型

属性、方法、字段 字段和属性的区别 在C#中&#xff0c;字段&#xff08;fields&#xff09;和属性&#xff08;properties&#xff09;都是类的成员&#xff0c;它们提供了类存储数据的方式&#xff0c;但它们在用途和功能上有着明显的区别。 字段 字段通常用来存储类…

Gstreamer配合srs服务器实现RTMP直播和WebRtc直播

前言 上一篇文章,实现了配合腾讯云直播的推流,但是需要花钱,于是就在思考能不能搞一个局域网内,免费的RTMP直播呢? 最终发现了可以使用srs服务器。如果成功了,以后也可以使用webrtc的直播推流。 以下是实现效果: 一、搭建srs服务器: 参考:ubuntu环境下搭建SRS服务器(…

MyBatis全方位指南:从注解到XML文件的数据库操作

目录 一.什么是MyBatis 入门程序初体验 二.MyBatis基本操作CRUD ▐ 增(Insert) 返回主键 ▐ 删(Delete) ▐ 改(Update) ▐ 查(Select) 起别名 结果映射 开启驼峰命名(推荐) 三.MyBatis XML配置文件 ▐ 增(Insert) ▐ 删(Delete) ▐ 改(Update) ▐ 查(Select) …

Linux:Xshell相关配置及前期准备

一、Linux的环境安装 1、裸机安装或者是双系统 2、虚拟机的安装 3、云服务器&#xff08;推荐&#xff09;——>安装简单&#xff0c;维护成本低&#xff0c;学习效果好&#xff0c;仿真性高&#xff08;可多人一起用一个云服务器&#xff09; 1.1 购买云服务器 使用云服…

基于环形拓扑的多目标粒子群优化算法(MO_Ring_PSO_SCD)求解无人机三维路径规划(MATLAB代码)

一、无人机多目标优化模型 无人机三维路径规划是无人机在执行任务过程中的非常关键的环节&#xff0c;无人机三维路径规划的主要目的是在满足任务需求和自主飞行约束的基础上&#xff0c;计算出发点和目标点之间的最佳航路。 1.1路径成本 无人机三维路径规划的首要目标是寻找…

【传知代码】Flan-T5 使用指南(论文复现)

当今&#xff0c;自然语言处理技术正在以前所未有的速度和精度发展。在这个领域中&#xff0c;Flan-T5作为一种新兴的预训练语言模型&#xff0c;正吸引着广泛的关注和应用。Flan-T5不仅仅是一个强大的文本生成工具&#xff0c;它还能通过提供高效的语义理解和多任务学习能力&a…

springboot配置多个数据源

实际业务中&#xff1b;在一个项目里面读取多个数据库的数据来进行展示&#xff0c;例如读取mysql&#xff0c;pgsql&#xff0c;oracle的不同数据库&#xff0c;springboto对同时配置多个数据源是支持的。 使用springbootmybatis的框架来进行演示&#xff0c; 在配置文件中配…

美国失业率大幅上升,增加九月份降息利率的可能性

令人失望的是&#xff0c;美国7月份经济增加了11.4万个工作岗位&#xff0c;低于预期的17.5万个和6月的17.9万个。平均小时工资持续下降&#xff0c;但失业率升至4.3%。美元继续走低&#xff0c;美国国债也在下跌&#xff0c;而黄金则获得了提振。 7月份的非农业支付数据令人失…

鸿蒙 IM 即时通讯开发实践,融云 IM HarmonyOS NEXT 版

融云完成针对“纯血鸿蒙”操作系统的 SDK 研发&#xff0c;HarmonyOS NEXT 版融云 IM SDK 已上线&#xff0c;开发者可在“鸿蒙生态伙伴 SDK 市场”查询使用。 发挥 20 年通信行业技术积累和领创品牌效应&#xff0c;融云为社交、娱乐、游戏、电商、出行、医疗等各行业提供专业…

react引入高德地图并初始化卫星地图

react引入高德地图并初始化卫星地图 1.安装依赖 yarn add react-amap amap/amap-jsapi-loader2.初始化地图 import AMapLoader from "amap/amap-jsapi-loader"; import { FC, useEffect, useRef, useState } from "react";const HomeRight () > {con…

普通人有必要学Python吗?学了之后能做什么?

目录 首先来说一下极其推荐的方向&#xff1a; 1、数据分析 2、科学计算 3、大数据框架 4、脚本开发 5、爬虫 6、Web框架 总结&#xff1a; 如果你还没有开始使用Python&#xff0c;答应我&#xff0c;把这个回答看完&#xff0c;如果你真的学习并深入使用过Python&…

我的最爱之《达明一派》

达明一派&#xff0c;是我最爱。刘以达(Tats)与黄耀明(Anthony Wong)在1980年代的香港组成的二人流行音乐组合&#xff0c;在90年代&#xff0c;网络还没兴起时&#xff0c;那是卡带流行的岁月。90年代&#xff0c;我与好友&#xff0c;同考大学&#xff0c;他留在了南充读读书…

使用labelme生成mask数据集(亲测可行)

1、下载label.exe文件 链接&#xff1a;github地址 2、安装一下anaconda&#xff0c;百度一下直接安装就行 3、打开labelme.exe文件&#xff0c;直接加载图片&#xff0c;然后编辑多边形&#xff0c;就是mask的位置 4、画好mask了&#xff0c;保存为json文件&#xff0c;记住这…

【qiankun微前端】基座主应用(vue2)+多个微应用(任意框架)

前言 前段时间对我们已有的工程进行了微前端改造,后来思考一下微前端的本质,查询了不少资料,从qiankun微前端示例中学到了不少。 微前端的核心,似乎应该是一个基座应用(含登录页,layout页,404和首页等),多个子应用(任意框架,提供内部页面内容),下面就对这个思路…

stm32入门-----软件I2C读写MPU6050

目录 前言 MPU6050 1.简介 2.相关参数 3.硬件电路 4.MPU6050框图 C编程实现I2C读写MPU6050步骤 1.MyI2C.c文件 &#xff08;1&#xff09;引脚的宏定义 &#xff08;2&#xff09;对SCL和SDA的操作以及初始化 &#xff08;3&#xff09;起始信号标志 &#xff08;4…

数据结构(面试)

目录 线索二叉树哈夫曼树并查集最小生成树最短路径拓扑排序二叉排序树平衡二叉树红黑树折半查找散列表堆排序归并排序 线索二叉树 原理&#xff1a;利用树节点的n1个左右空指针指向其遍历序列的前驱和后继&#xff08;线索&#xff09; 优点&#xff1a;简化遍历&#xff0c;不…

7.2 单变量(多->多),attention/informer

继续上文书写&#xff1a; 1 GRU Attention 收敛速度稳定的很多&#xff0c;你看这些模型是不是很容易搭&#xff0c;像积木一样&#xff1b; def create_model(input_shape, output_length,lr1e-3, warehouse"None"):input Input(shapeinput_shape)conv1 Conv…