Java学习记录(十七)IO流(三)

转换流(在字节流中想使用字符流的方法时使用)

转换流是字节流和字符流之间的桥梁,转换流本身其实就是字符流所以可以使用字符流里的相关方法,通过InputStreamReader字符转换输入流能将字节流转化为字符流输入到内存中,而在内存中之后能使用OutputStreamWriter字符转换输出流将字符流转化为字节流输出,如下:

使用字符流对相应的文件进行相应的解码方式解码,例如一个GBK解码方式的文件数据,我想在idea中看到他的文件数据,但是idea是默认的采用UTF-8解码方式的,所以在idea中看到该文件的数据是一堆乱码,此时我就需要字符流中的FileReader 也就是字符输入流进行解码,格式如下:

FileReader fr = new FileReader("D:\\11Codingtext\\MyIO\\gbkfile.txt", Charset.forName("GBK"));

FileReader的解码用法

在创建FileReader的时候不仅可以输入需要读取的文件地址,还可以传入相关的解码方式,例如GBK,UTF-8,这样的话就能对该文件中的数据按照该解码方式进行读取到程序中,代码如下:

package com.itazhang.Demo1;import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;public class ConvertStreamDemo1 {public static void main(String[] args) throws IOException {
//        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\11Codingtext\\MyIO\\gbkfile.txt"),"GBK");
//        int temp;
//        while(true){
//            temp = isr.read();
//            if(temp == -1){
//                break;
//            }
//            System.out.print((char)temp);
//        }
//        isr.close();//以下为jdk11之后的替代方案FileReader fr = new FileReader("D:\\11Codingtext\\MyIO\\gbkfile.txt", Charset.forName("GBK"));int temp;while(true){temp = fr.read();if(temp == -1){break;}System.out.print((char) temp);}fr.colse();}
}

FileWriter的解码用法

在创建FileWriter的时候不但可以输入需要传入的文件位置,还可以在后面输入需要传入数据所对应的解码方式,这样就能将相关解码方式的数据存储到相应的文件中,例如:

FileWriter fw =new FileWriter("D:\\11Codingtext\\MyIO\\temp.txt",Charset.forName("GBK"));

具体创建代码如下:这样就能将GBK解码方式的数据放入到temp.txt文件中,如果不是使用GBK解码方式对该文件进行查看的话,只会看到一堆乱码。

 //通过FileWriter写出相关编码方式的数据FileWriter fw =new FileWriter("D:\\11Codingtext\\MyIO\\temp.txt",Charset.forName("GBK"));fw.write("这是一个测试语句");fw.close();

练习(一)

利用FileReader和FileWriter中的read和write方法将一个文件中的GBK解码方式的数据读取到程序中,且将其用UTF-8的解码方式写入到指定的其他文件中,具体实现代码如下:

package com.itazhang.Demo1;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;public class CoverntStreamDemo2 {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("D:\\11Codingtext\\MyIO\\temp.txt", Charset.forName("GBK"));FileWriter fw = new FileWriter("D:\\11Codingtext\\MyIO\\temp2.txt",Charset.forName("UTF-8"));int temp;while(true){temp = fr.read();if(temp == -1){break;}fw.write((char)temp);}fw.close();fr.close();}
}

源文件在Idea中的显示,因为采用的是GBK解码方式,idea是采用的UTF-8解码方式,所以看到的数据是以乱码的形式展现 

在实现上诉代码并将其写入到temp2文件之后,如下正常显示出来了

练习(二)

将一个文件用字节流取出,且读取到程序中的时候一次读取一行,且在写入新文件的时候,写入一行就换行。

需求分析:上诉功能因为每次读取一行的功能是BufferedReader所特有的,且写入一行换行也是BufferedWriter所特有的,但是题目要求我们用字节流取出,所以这个时候就会用到转换流的方法,这个时候就会先创建字节流FileInputStream将数据读取出来,再用转换流将该字节流转化为字符流,再用该字符流创建字符流的高级流BufferedReader,这样就能实现每次读取一行的功能,同样的输出的时候每输出一行换行操作也是字符流的高级流BufferedWriter所特有的功能,根据上诉的功能要求,通过不断的创建转化从而实现上诉题目的需求,具体代码如下:

package com.itazhang.Demo2;import java.io.*;public class ConvertStreamExercise3 {public static void main(String[] args) throws IOException {FileInputStream fi = new FileInputStream("D:\\11Codingtext\\MyIO\\a.txt");InputStreamReader isr = new InputStreamReader(fi);BufferedReader br =new BufferedReader(isr);FileOutputStream fo = new FileOutputStream("D:\\11Codingtext\\MyIO\\temp3.txt");OutputStreamWriter osw = new OutputStreamWriter(fo);BufferedWriter bw = new BufferedWriter(osw);String temp;while(true){temp = br.readLine();if(temp == null){break;}bw.write(temp);bw.newLine();}bw.close();br.close();}
}

当然在常见字符流和转换流和字符流的高级流BufferedReader这三步可以嵌套成一步

FileInputStream fi = new FileInputStream("D:\\11Codingtext\\MyIO\\a.txt");
InputStreamReader isr = new InputStreamReader(fi);
BufferedReader br =new BufferedReader(isr);

改为:

BufferedReader br =new BufferedReader(new InputStreamReader(new FileInputStream("D:\\11Codingtext\\MyIO\\a.txt")));

转换流总结:

序列化流 

序列化流能将Java中的对象写入到本地文件中,其实质为字节流的高级流,所以在创建的时候需要关联字节流中的基本流

创建之后,因为传递对象到本地文件,这个对象的类需要实现一个接口Serializable,但是这是一个标记型接口,哪个类实现了该接口说明该类创建出的对象可以被序列化,里面是没有方法的,这样之后,就能将对象写入到本地文件中了。

需要添加的对象学生类如下:

package com.itazhang.Demo3;import java.io.Serializable;public class Student implements Serializable {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}

 

具体实现代码如下:

package com.itazhang.Demo3;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class ObjecyStreamDemo1 {public static void main(String[] args) throws IOException {Student stu = new Student("azhang",22);//创建序列化流,因为时字节流的高级流,所以需要先创建字节流基础流再包装成序列化流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\11Codingtext\\MyIO\\c.txt"));//用Write方法将对象写入到本地文件oos.writeObject(stu);//释放资源oos.close();}
}

反序列化流 

反序列化流也是字节流的高级流,他也是再字符输入流FileInputStream的基础上包装而成,所以在创建该高级流之前,需要关联一个字符输出流,该高级流的作用其实就是将通过序列化流存储到文件中的对象通过该类的readObject方法读取到程序中,具体代码实现如下:

//创建反序列化流,读取文件中的数据并返回到程序中ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\11Codingtext\\MyIO\\c.txt"));//用readObject方法将数据读取出来并返回到程序中Object o = ois.readObject();System.out.println(o);//释放资源ois.close();

序列化和反序列化的问题

在将一个对象序列化放入到本地文件之后,后面可能我将该对象的类里进行一系列的修改,例如增添成员遍历,这时候,将该文件的数据反序列化读取到文件的时候就会报错,因为在我们将该对象序列化并输出到文件的时候,Java在底层就会生成一个该类的版本号,这个版本号会固定该类的格式,而在我们修改了类里面的数据例如成员变量的时候,这个时候Java里面的该类版本号就会发生改变,但是存储到文件里的数据版本号还是之前的,所以在反序列化的时候,Java将这两个版本号进行比对就会失败,最终导致报错

那么怎么解决上述问题呢,我们就可以直接将需要序列化的对象的类的版本号固定死,这样无论之后对该类进行怎样的修改,之前序列化保持的文件数据版本号就会始终与类里的版本号一致。使用idea自带的uid生成,这样可以自动根据我们当前类里面 的方法属性等生成一个固定的版本号。

如下为idea自动生成的版本号

但是如果我类里的一些数据不想被序列化到本地文件怎么办呢,这个时候可以在相关属性前面加上transient关键字,这个关键字的意思是瞬态关键字,他所修饰的属性不会被序列化到本地文件

序列化流与反序列化流总结

注意:一次序列化只能向文件写入一个对象,一次反序列化也只能从文件中读取一个对象。如果需要读取或写入多个对象的话,则需要多次使用序列化流和反序列化流。但是一般不会多次重复写入和读取对象,一般采用将需要序列化存入文件的对象用Arraylist集合存储起来,直接序列化这个集合,将集合里所有对象序列化存入到该文件中。同理,需要读取一个文件存储的对象使用反序列化时,我们一般采用Arraylist集合去接收这些对象,这样的话方便我们序列化和反序列化多个对象

具体实现代码如下:

package com.itazhang.Demo3;import java.io.*;
import java.util.ArrayList;
import java.util.Collections;public class ObjecyStreamDemo1 {public static void main(String[] args) throws IOException, ClassNotFoundException {Student stu= new Student("azhang",22,"001");Student stu1= new Student("azhan",22,"001");Student stu2= new Student("azha",22,"001");Student stu3= new Student("azh",22,"001");//用集合存储需要序列化的对象ArrayList<Student> list1 =new ArrayList<>();Collections.addAll(list1,stu,stu1,stu2,stu3);//创建序列化流,因为时字节流的高级流,所以需要先创建字节流基础流再包装成序列化流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\11Codingtext\\MyIO\\c.txt"));//用Write方法将对象写入到本地文件oos.writeObject(list1);//释放资源oos.close();//创建反序列化流,读取文件中的数据并返回到程序中ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\11Codingtext\\MyIO\\c.txt"));//用readObject方法将数据读取出来并返回到程序中ArrayList<Student> list2 =new ArrayList<>();list2 = (ArrayList<Student>) ois.readObject();System.out.print(list2+" ");//释放资源ois.close();}
}

打印流

打印流只能输出,不能读取,打印流分为printStream和printWriter,printStream是字节打印流,printWriter是字符打印流,打印流能将数据打印到指定文件里

字节打印流printStream

 

字符打印流printWriter 

压缩和解压缩流 

压缩和解压缩流,顾名思义就是用来压缩文件和解压文件的,他们都是属于字节流的高级流,压缩流是用来将程序数据写入到文件中,解压缩流是用来将文件中的数据读取到程序中

解压缩流

ZipInputStream是一个解压缩流,他的作用是将压缩包里面的数据读取到程序中,也就是执行读取的功能,他的底层是基于FileInputStream,他是该字节流的高级流,所以再创建他的时候跟之前的高级流创建一样,都是需要先创建底层的流,再用高级流方法将其包装,具体创建代码如下:

ZipInputStream zip = new ZipInputStream(new FileInputStream(src));

具体解压代码如下:

/*
*   解压缩流
*
* */
public class ZipStreamDemo1 {public static void main(String[] args) throws IOException {//1.创建一个File表示要解压的压缩包File src = new File("D:\\aaa.zip");//2.创建一个File表示解压的目的地File dest = new File("D:\\");//调用方法unzip(src,dest);}//定义一个方法用来解压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);if(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();}
}

压缩流

压缩一个文件的代码具体如下:

public class ZipStreamDemo2 {public static void main(String[] args) throws IOException {/**   压缩流*      需求:*          把D:\\a.txt打包成一个压缩包* *///1.创建File对象表示要压缩的文件File src = new File("D:\\a.txt");//2.创建File对象表示压缩包的位置File dest = new File("D:\\");//3.调用方法用来压缩toZip(src,dest);}/**   作用:压缩*   参数一:表示要压缩的文件*   参数二:表示压缩包的位置* */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);}zos.closeEntry();zos.close();}
}

压缩一个文件夹的代码具体如下:

public class ZipStreamDemo3 {public static void main(String[] args) throws IOException {/**   压缩流*      需求:*          把D:\\aaa文件夹压缩成一个压缩包* *///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();}/**   作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中*   参数一:数据源*   参数二:压缩流*   参数三:压缩包内部的路径* */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对象,放入到压缩包当中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}}}
}

 Commons工具包

该包里提供了许多的工具类,需要调用直接用工具类调用即可,特别是IO操作,如之前的复制文件,复制文件夹,删除文件,删除文件夹都能通过调用里面的工具类的相关方法实现

例如相关拷贝方法:

copy方法有多个重载方法,满足不同的输入输出流

IOUtils.copy(InputStream input, OutputStream output)

IOUtils.copy(InputStream input, OutputStream output, int bufferSize)//可指定缓冲区大小

IOUtils.copy(InputStream input, Writer output, String inputEncoding)//可指定输入流的编码表

IOUtils.copy(Reader input, Writer output)

IOUtils.copy(Reader input, OutputStream output, String outputEncoding)//可指定输出流的编码表

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

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

相关文章

YOLOv8改进 | 注意力机制 | 添加YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

一、本文介绍 本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM,SEAM(Spatially Enhanced Attention Module)注意力网络模块旨在补偿被遮挡面部的响应损失,通过增强未遮挡面部的响应来实现这一目标,其希望通过学习遮挡面和未遮挡面之间的…

.net core框架

ASP.NET Core 入门 跨平台开源框架 B/S 类与方法 Console 部分称为“类”。 类“拥有”方法&#xff1b;或者可以说方法存在于类中。 WriteLine() 部分称为“方法”。 想要使用方法就要知道方法在哪里 —————————— 执行流 一次执行一段 ASP.NET Core 是什么东西…

VikeCTF 2024

VikeCTF 2024 WP 由于环境原因很多靶场的过程图片没法复现截图。。。 web Ponies 算是一个签到题&#xff0c;看到源码这里其实是一个快速跳转的程序&#xff0c;我们看到tag.src直接进行访问&#xff0c;可以看到源码里面&#xff0c;从里面分析拿到flag function recurs…

流畅的Python(十八)-使用asyncio包处理并发

一、核心要义 1. 对比一个简答的多线程程序和对应的asyncio版,说明多线程和异步任务之间的关系 2. 网络下载的异步版 3. 在异步编程中,与回调相比&#xff0c;协程显著提升性能的方式 二、代码示例 1、相关知识点 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time …

算法50:动态规划专练(力扣514题:自由之路-----4种写法)

题目: 力扣514 &#xff1a; 自由之路 . - 力扣&#xff08;LeetCode&#xff09; 题目的详细描述&#xff0c;直接打开力扣看就是了&#xff0c;下面说一下我对题目的理解: 事例1&#xff1a; 输入: ring "godding", key "gd" 输出: 4. 1. ring的第…

RStudio更换R语言版本

今天下载R语言用于读取.xlsx文件的readxl包时&#xff0c;RStudio提示该包是使用R-4.3.3版本构建&#xff0c;而我现在使用的是R-4.3.2版本&#xff0c;所以需要升级一下R语言版本&#xff0c;这里先下载最新版本的R语言&#xff0c; 下载地址&#xff1a;The Comprehensive R…

Jenkins自动构建 CI/CD流水线学习笔记(从入门到入土,理论+示例)

文章目录 1、什么是Jenkins的流水线?2、流水线语法2.1、声明式流水线2.2、脚本化流水线 3、流水线示例3.1、使用声明式流水线的语法编写的 Jenkinsfile 文件3.2、Pipeline 各种语言示例3.2.1 Java&#xff1a;3.2.2 Node.js / JavaScript3.2.3 Python 4、一套完整的Devops Jen…

【ICCV21】Swin Transformer: Hierarchical Vision Transformer using Shifted Windows

文章目录 0. Abstract1. Introduction2. Related Work3. Method3.1 Overall Architecture3.2 Shifted Window based Self-Attention3.3 Architecture Variants 4. Experiments4.1 Image Classification on ImageNet-1K4.2 Object Detection on COCO4.3 Semantic Segmentation o…

基于JavaWeb开发的springboot网咖管理系统[附源码]

基于JavaWeb开发的springboot网咖管理系统[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &a…

【办公类-40-02】20240311 python模仿PPT相册功能批量插入照片,更改背景颜色 (家长会系列二)

作品展示——用Python插入PPT相册 背景需求&#xff1a; 马上就要家长会&#xff0c;我负责做会议前的照片滚动PPT&#xff0c;通常都是使用PPT的相册功能批量导入照片&#xff0c; 生成给一个新的PPT文件 更改背景颜色 设置4秒间隔&#xff0c;应用到全部 保存&#xff0c;改…

Hadoop伪分布式配置--没有DataNode或NameNode

一、原因分析 重复格式化NameNode 二、解决方法 1、输入格式化NameNode命令&#xff0c;找到data和name存放位置 ./bin/hdfs namenode -format 2、删除data或name&#xff08;没有哪个删哪个&#xff09; sudo rm -rf data 3、重新格式化NameNode 4、重新启动即可。

sheng的学习笔记- AI-类别不平衡问题

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 什么是类别不平衡问题 类别不平衡&#xff08;class-imbalance&#xff09;&#xff0c;也叫数据倾斜&#xff0c;数据不平衡&#xff0c;就是指分类任务中不同类别的训练样例数目差别很大的情况。 例如有998个反例&#xf…

vue3全局引入element-plus后怎么使用Message进行消息提示

全局引入 main.ts import element-plus/dist/index.css 在需要使用提示的组件中引入 import { ElMessage } from element-plus 使用举例

Verilog刷题笔记37

题目&#xff1a;3位二进制加法器 Now that you know how to build a full adder, make 3 instances of it to create a 3-bit binary ripple-carry adder. The adder adds two 3-bit numbers and a carry-in to produce a 3-bit sum and carry out. To encourage you to actua…

@Conditional注解详解

目录 一、Conditional注解作用 二、Conditional源码解析 2.1 Conditional源码 2.2 Condition源码 三、Conditional案例 3.1 Conditional作用在类上案例 3.1.1 配置文件 3.1.2 Condition实现类 3.1.3 Bean内容类 3.1.4 Config类 3.1.5 Controller类 3.1.6 测试结果 3…

Visual grounding-视觉定位任务介绍

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

Spring Cloud Alibaba微服务从入门到进阶(一)

Springboot三板斧 1、加依赖 2、写注解 3、写配置 Spring Boot Actuator Spring Boot Actuator 是 Spring Boot 提供的一系列用于监控和管理应用程序的工具和服务。 SpringBoot导航端点 其中localhost:8080/actuator/health是健康检查端点&#xff0c;加上以下配置&#xf…

基于element-plus的Dialog选择控件

翻看之前工程师写的vue2的代码&#xff0c;很多都是复制、粘贴&#xff0c;也真是搞不懂&#xff0c;明明可以写一个控件&#xff0c;不就可以重复使用。很多前端总喜欢element搞一下&#xff0c;ant-design也搞一下&#xff0c;有啥意义&#xff0c;控件也不是自己写的&#x…

Python递归函数你用对了吗?

1.递归函数 递归函数&#xff1a;函数自己调用自己 2.需求 使用函数的方式&#xff0c;计算数字n的阶乘 # 5&#xff01; """ 5! 1 * 2 * 3 * 4 * 5 4! 1 * 2 * 3 * 4 3! 1 * 2 * 3 2! 1 * 2 1! 1综上可以总结出&#xff1a;n! n * (n - 1) "&qu…

什么是防静电晶圆隔离膜?一分钟让你了解抗静电晶圆隔离纸

防静电晶圆隔离膜&#xff0c;也被称为防静电蓄积纸、硅片纸、半导体晶圆盒内缓冲垫片等多种名称&#xff0c;是半导体制造和运输过程中的一种重要辅助材料。 该隔离膜具备多种特性&#xff0c;如防静电、无尘、不掉屑、强韧耐用等&#xff0c;这些特性使其在半导体制造和运输中…