Java的编程之旅41——字符流

目录

1.字符流的简介

2.字符的编码与解码

 3.字符流读写操作

1.字符流写入

2.字符流复制文件

4.FileWriter&FileReader

5.缓冲区高效读写

6.序列化与反序列化


1.字符流的简介

在Java中,字符流是用于处理字符数据的输入输出流。它是以字符为单位进行处理,而不是字节。字符流主要用于处理文本文件,可以直接读取和写入字符数据。

Java提供了两种字符流:字符输入流和字符输出流。

字符输入流:

  • FileReader:用于读取字符数据的输入流。它继承自Reader类,可以读取字符文件的内容。
  • BufferedReader:用于读取字符数据的缓冲输入流。它继承自Reader类,可以提供更高效的字符读取操作。

字符输出流:

  • FileWriter:用于写入字符数据的输出流。它继承自Writer类,可以将字符数据写入文件。
  • BufferedWriter:用于写入字符数据的缓冲输出流。它继承自Writer类,可以提供更高效的字符写入操作。

使用字符流进行读写操作的一般步骤如下:

  1. 创建字符输入流或者字符输出流对象,参数为要读取或写入的文件。
  2. 使用字符输入流或者字符输出流的相应方法进行读取或写入操作。
  3. 关闭字符流。

2.字符的编码与解码

字符分为GBK格式和UTF-8格式,当我们想用GBK格式编码的时候就需要用GBK格式进行解码,UTF-8格式同理

//GBK格式
byte[] gbk = "hello java".getByte("GBK");
System.out.println(new String(gbk,"GBK"));//UTF-8格式
byte[] utf = "hello java".getByte("UTF-8");
System.out.println(new String(utf,"UTF-8"));

 3.字符流读写操作

1.字符流写入

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./test.txt"));
osw.write("hello world");
osw.close();InputStreamReader isr = new InputStreamReader(new InputStreamRead("./test.txt"));
int ch;
while((ch = isr.read()) != -1){System.out.println((char)ch);
}
isr.close();

以上代码是用字符流进行文件的写入和读取操作。

首先,代码创建了一个OutputStreamWriter对象osw,它使用FileOutputStream来创建文件输出流。这意味着我们将要写入的数据将被写入到test.txt文件中。

然后,使用osw的write方法将字符串"hello world"写入到输出流中,这个字符串将会被写入到test.txt文件中。

最后,调用osw的close方法来关闭输出流。

接下来,代码创建了一个InputStreamReader对象isr,它使用FileInputStream来创建文件输入流。这意味着我们将从test.txt文件中读取数据。

然后,使用isr的read方法读取文件中的字符数据。read方法返回的是读取到的字符的Unicode编码。在while循环中,将读取到的字符强制转换为char类型,并打印出来。

最后,调用isr的close方法来关闭输入流。

总结起来,以上代码的执行过程如下:

  1. 创建一个字符输出流,将字符串"hello world"写入到文件test.txt中。
  2. 创建一个字符输入流,从文件test.txt中读取字符数据,并将其打印出来。
  3. 关闭字符输出流和字符输入流。

注意事项:

  • 在使用字符流进行读写操作时,需要进行异常处理,确保流的正确关闭。
  • 运行以上代码前,需要确保test.txt文件不存在或者为空,否则将会被覆盖。

2.字符流复制文件

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./newtest.txt"));
InputStreamReader isr = new InputStreamReader(new FileInputStream("./test.txt"));int len;
char[] ch = new char[1024];
while((len = isr.read(ch)) != -1){osw.write(ch,0,len);osw.flush();
}osw.close();
isr.close();

以上代码是使用字符流进行文件的复制操作。

首先,代码创建了一个OutputStreamWriter对象osw,它使用FileOutputStream来创建文件输出流,文件名为newtest.txt。这意味着我们将要将数据写入到newtest.txt文件中。

接着,代码创建了一个InputStreamReader对象isr,它使用FileInputStream来创建文件输入流,文件名为test.txt。这意味着我们将从test.txt文件中读取数据。

然后,代码使用一个字符数组ch来缓存从文件输入流中读取的字符数据。len表示每次从输入流中读取的字符数。

在while循环中,通过isr的read方法将字符数据读取到ch数组中,并将实际读取的字符数赋值给len。当读取到文件末尾时,read方法将返回-1,循环结束。

然后,通过osw的write方法将ch数组中的字符数据写入到输出流中。这样,我们就实现了从输入流中读取数据,并将数据写入到输出流中,即完成了文件的复制操作。

注意,在每次写入数据后,通过osw的flush方法将缓冲区中的数据强制刷新到文件中,确保数据能够被及时写入。

最后,调用osw和isr的close方法关闭输出流和输入流。

总结起来,以上代码的执行过程如下:

  1. 创建一个字符输出流,将数据写入到newtest.txt文件中。
  2. 创建一个字符输入流,从test.txt文件中读取数据。
  3. 循环读取输入流中的字符数据,并将其写入到输出流中,实现文件的复制。
  4. 关闭字符输出流和字符输入流。

注意事项:

  • 在使用字符流进行读写操作时,需要进行异常处理,确保流的正确关闭。
  • 运行以上代码前,需要确保test.txt文件存在且有内容,否则将无法复制数据到newtest.txt文件中。

4.FileWriter&FileReader

FileWriterFileReader 是 Java IO 包中用于文件的读写操作的类。

FileWriter 是一个字符输出流,用于将字符数据写入文件。它继承自 Writer 类,可以使用 write() 方法将字符写入文件。如果文件不存在,FileWriter 会自动创建文件;如果文件已存在,则会覆盖原有内容。

FileReader 是一个字符输入流,用于从文件中读取字符数据。它继承自 Reader 类,可以使用 read() 方法来读取文件中的字符。如果文件不存在或无法读取,FileReader 会抛出 FileNotFoundException

这两个类都是以字符为单位进行读写操作,适用于处理文本文件。它们通常与字符数组配合使用,可以一次读取或写入多个字符。

需要注意的是,FileWriterFileReader 在读写文件时,并不会进行字符编码的转换。如果需要处理不同字符编码的文件,可以使用 InputStreamReaderOutputStreamWriter 来进行字符编码的转换操作。

        FileReader fr = new FileReader("./test.txt");FileWriter fw = new FileWriter("./newtest.txt");int len;char[] chars = new char[1024];while((len = fr.read(chars)) != -1){fw.write(chars,0,len);}fr.close();fw.close();

这段代码使用 FileReaderFileWriter 来实现文件的读取和写入。

首先,创建一个 FileReader 对象 fr,并指定读取的文件路径为 "./test.txt"。 然后,创建一个 FileWriter 对象 fw,并指定写入的文件路径为 "./new.txt"。

接下来,通过一个循环,不断从 fr 读取字符,将读取的字符存入一个字符数组 chars 中,并将读取的字符个数赋值给 len。 如果 len 不等于 -1,说明还有未读取的字符,将 chars 数组中的内容通过 fw 写入到指定文件中。这里使用 write(char[] cbuf, int off, int len) 方法来写入指定长度的字符数组。

最后,关闭 frfw,释放资源。

这段代码的作用是将 "./test.txt" 文件中的内容复制到 "./new.txt" 文件中。

5.缓冲区高效读写

BufferReader br = new BufferReader("./test.txt");
BufferWriter bw = new BufferWriter("./newtest.txt");
int len;
char[] ch = new char[1024];
while((len = br.read(ch)) != -1){bw.write(ch,0,len);
}br.close();
bw.close();

代码中的 BufferedReaderBufferedWriter 是 Java IO 包中的缓冲字符流类,它们提供了对字符数据的缓冲读写功能,可以提高读写效率。

BufferedReader 是字符输入流,用于读取字符数据。它继承自 Reader 类,可以使用 read() 方法来读取文件中的字符。与 FileReader 不同的是,BufferedReader 会将数据缓存在内存中,以提高读取的效率。

BufferedWriter 是字符输出流,用于写入字符数据。它继承自 Writer 类,可以使用 write() 方法将字符写入文件。与 FileWriter 不同的是,BufferedWriter 会将数据缓存在内存中,以提高写入的效率。

在代码中,首先创建了一个 BufferedReader 对象,用于读取名为 "test.txt" 的文件。然后创建了一个 BufferedWriter 对象,用于写入名为 "newtest.txt" 的文件。

接下来,通过一个循环,使用 read() 方法从输入流中读取字符数据,并将其存储在字符数组 ch 中。然后使用 write() 方法将字符数组中的数据写入输出流。

循环会一直执行直到 read() 方法返回 -1,表示文件已读取完毕。最后,关闭输入流和输出流,释放资源。

使用 BufferedReaderBufferedWriter 可以提高读写效率,因为它们会将数据缓存起来,减少了对文件的实际读写次数。

缓冲区特有的方法

BufferReader br = new BufferReader("./test.txt");
BufferWriter bw = new BufferWriter("./newtest.txt");String line;
while((line = br.readLine()) != null){bw.write(line);bw.newLine();bw.flush();
}br.close();
bw.close();

代码中的 BufferedReaderBufferedWriter 是 Java IO 包中的缓冲字符流类,它们提供了对字符数据的缓冲读写功能,可以提高读写效率。

BufferedReader 是字符输入流,用于读取字符数据。它继承自 Reader 类,可以使用 readLine() 方法逐行读取文件中的字符数据。与 FileReader 不同的是,BufferedReader 会将数据缓存在内存中,以提高读取的效率。

BufferedWriter 是字符输出流,用于写入字符数据。它继承自 Writer 类,可以使用 write() 方法将字符写入文件。与 FileWriter 不同的是,BufferedWriter 会将数据缓存在内存中,以提高写入的效率。

在代码中,首先创建了一个 BufferedReader 对象,用于读取名为 "test.txt" 的文件。然后创建了一个 BufferedWriter 对象,用于写入名为 "newtest.txt" 的文件。

接下来,通过一个循环,使用 readLine() 方法从输入流中逐行读取文本数据,并将每行数据存储在变量 line 中。然后使用 write() 方法将每行数据写入输出流,并调用 newLine() 方法插入换行符。最后,使用 flush() 方法将缓冲区的数据刷新到文件中。

循环会一直执行直到 readLine() 方法返回 null,表示文件已读取完毕。最后,关闭输入流和输出流,释放资源。

使用 BufferedReaderBufferedWriter 可以提高读写效率,因为它们会将数据缓存起来,减少了对文件的实际读写次数。同时,使用 readLine() 可以逐行读取文本数据,方便处理文本文件的内容。

6.序列化与反序列化

序列化和反序列化是指将对象转换成字节流的过程,以便在需要时可以将字节流重新转换为对象。序列化可以用于对象的持久化存储、网络传输等场景。

在序列化过程中,对象的状态信息(即对象的数据)被转换为字节流,可以通过将字节流写入文件或通过网络传输来保存。反序列化过程恢复字节流,将其转换为原始对象。

序列化和反序列化可以用于不同的编程语言之间的对象传输,因为字节流是一种通用的数据格式。

在Java中,可以使用Serializable接口将对象标记为可序列化的,然后使用ObjectOutputStream将对象序列化为字节流,使用ObjectInputStream将字节流反序列化为对象。

1.定义一个学生信息类

public class Student extends Serializable {private String name;private String sex;private int age;private float score;public Student(String name, String sex, int age, float score) {this.name = name;this.sex = sex;this.age = age;this.score = score;}public String getName() {return name;}public String getSex() {return sex;}public int getAge() {return age;}public float getScore() {return score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +", score=" + score +'}';}
}

2.序列化对象

public class Serializable {public static void main(String[] args) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./test.txt"));Student student = (Student)ois.readObject();System.out.println(student.getName());System.out.println(student.getSex());System.out.println(student.getAge());System.out.println(student.getScore());ois.close();}
}

这段代码实现了反序列化操作,读取保存在文件中的序列化对象并将其恢复为原始的Java对象。

首先,创建了一个ObjectInputStream对象ois,并通过它的构造方法将文件"./test.txt"与该ObjectInputStream关联起来。

接下来,通过ois调用readObject()方法,从文件中读取对象,并将其类型转换为Student对象。这里假设文件中保存的是一个Student对象,并且已经进行了序列化操作。

然后,通过Student对象的getter方法,获取Student对象中的各个属性值,并将其输出到控制台。

最后,通过ois调用close()方法关闭ObjectInputStream流,释放资源。

需要注意的是,如果文件中保存的对象类型与读取时转换的类型不匹配,会抛出ClassCastException异常。另外,如果文件中没有保存任何对象或文件不存在,会抛出FileNotFoundException异常。如果文件中保存的是非序列化的对象,会抛出InvalidClassException异常。

另外,代码中的Student类需要实现Serializable接口,以便进行序列化和反序列化操作。在Student类中,需要注意成员变量的访问修饰符为private,同时提供公共的getter和setter方法,以便在序列化和反序列化过程中访问和修改对象的属性值。

 3.定义测试类

public class Ts {public static void main(String[] args) throws IOException {FileWriter();Student newStu = FileReader();System.out.println(newStu);}/*** 读取学生信息* @throws FileNotFoundException*/public static Student  FileReader() throws IOException {BufferedReader br = new BufferedReader(new FileReader("./test.txt"));String message = br.readLine();String[] sp = message.split(",");br.close();return new Student(sp[0],sp[1],Integer.parseInt(sp[2]),Integer.parseInt(sp[3]));}/*** 写入学生信息* @throws IOException*/public static void FileWriter() throws IOException {Student student = new Student("小李","女",18,98);BufferedWriter bw = new BufferedWriter(new FileWriter("./test.txt"));String message = student.getName() + "##" + student.getSex() + "##" +student.getAge() + "##" + student.getScore();bw.write(message);bw.close();}
}

这段代码实现了文件的读写操作,用于存储和读取学生对象的信息。

首先,创建了一个名为FileWriter()的方法,在该方法中创建了一个Student对象并赋值。然后,通过BufferedWriter类将Student对象的信息以特定的格式写入到文件"./test.txt"中。以"##"分隔不同属性值,并使用换行符分隔不同学生对象的信息。最后,通过bw调用close()方法关闭BufferedWriter流,释放资源。

接下来,创建了一个名为FileReader()的方法,在该方法中创建了一个BufferedReader对象,并通过其构造方法将文件"./test.txt"与该BufferedReader关联起来。然后,通过br调用readLine()方法一次读取一行数据,将其保存在字符串变量message中。

接着,通过split()方法将message字符串按照逗号分隔成一个字符串数组sp,数组中的每个元素对应一个学生对象的属性值。

然后,通过返回一个新的Student对象,将数组sp中的各个值赋给Student对象的相应属性。其中,通过Integer.parseInt()方法将字符串转换为整数类型。

最后,通过br调用close()方法关闭BufferedReader流,释放资源。

在main()方法中,首先调用FileWriter()方法将学生对象的信息写入文件。然后,调用FileReader()方法读取文件中的学生信息,并将返回的Student对象赋给newStu。最后,通过System.out.println输出newStu对象的信息。

需要注意的是,在写入和读取文件时,需要确保文件的路径和名称正确,并注意处理可能出现的异常情况,如文件不存在或写入失败等。此外,代码中的Student类需要与之前的例子中的Student类一致,包括属性和getter、setter方法的定义。

运行结果:

显示数组索引异常

我们需要把

private static final long serialVersionUID = -5116101128118950844L;

添加到Student类中,就不会出现异常了 

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

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

相关文章

读取txt文件并统计每行最长的单词以及长度

读取txt文件并统计每行最长的单词以及长度 题目 在 D:\\documant.txt 文本中,文件中有若干行英文文本,每行英文文本中有若干个单词,每个单词不会跨行出现每行至多包含100个字符,要求编写一个程序,处理文件,分析各行中的单词,找到每行中的最长单词,分别…

群晖docker安装sql server

安装步骤 开启群晖 SSH,通过 SSH 工具连接到群晖,运行下面的命令拉取mssql 2019 镜像 sudo docker pull mcr.microsoft.com/mssql/server:2019-latest然后在 docker 中就可以看到该镜像: 在群晖 docker 共享文件夹中创建 mssql2009 文件夹 …

ABAP - cl_gui_alv_grid cl_salv_table的各种处理

这篇文章主要是记录一下cl_gui_alv_grid 和 cl_salv_table 两种方式的ALV的字段,事件等的处理 举例,下面这个是用一个screen,显示2个ALV;上面这一个是用alv grid的;下面那一个是用salv去实现的 alv grid 主要涉及&am…

神舟通用-神通MPP

1、国产MPP 神通MPP是以多年大型通用数据库领域的研发实力为基础,集深厚的航天信息化建设经验,集成多项先进技术,为满足航天、政府、金融、电信等行业的海量数据分析统计应用需求而打造的分布式数据库软件,具有负载衡、在线扩展、…

基于ssm的志愿者招募系统的设计与实现(程序+文档+数据库)

** 🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅** 一、研究背景…

nginx有几种启动方式

Nginx 通常可以以两种主要的方式启动:作为前台进程运行或作为守护进程(后台)运行。 前台运行: 当Nginx以前台模式运行时,它会在命令行保持活动状态,所有的日志输出都会直接显示在命令行上。这种模式通常用于…

Redis底层数据结构之List

文章目录 1. Redis 6的list源码分析1. Redis 7的list源码分析 1. Redis 6的list源码分析 首先我们查看一下redis 6关于list的相关配置: config get list*可以看见redis 6的quicklist底层使用的数据结构是ziplist list-compress-depth:表示一个quicklis…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也,还被老板打电话push压力有点大的,还好搞的差不多了,明天再汇报,赶紧偷闲再刷几道题(可恶,被打破连更记录了)这几天刷的是动态规划,由于很成…

Node携手MongoDB探险旅行⛏️

Node携手MongoDB探险旅行⛏️ 本篇文章,学习记录于:尚硅谷🎢 文章简单学习总结:如有错误 大佬 👉点. 本篇不适合纯新手,因为本人已经使用很多数据库,很多数据库概念…就不会进行解释&#xff…

presto / trino plugin(自定义UDF函数)开发指南

方案1:自定义udf插件开发 1. Presto插件机制 presto不能像hive那样配置自定义的udf,而是采用插件机制实现。Presto 的插件(Plugin)机制,是 Presto 能够整合多种数据源的核心。通过实现不同的 Plugin,Presto 允许用户在不同类型的数据源之间进行 JOIN 等计算。Presto 内部的…

10、设计模式之外观模式(Facade)

一、什么是外观模式 这个大家一定是经常使用的,外观模式(门面模式)是一种结构型设计模式。它提供一个统一的接口,用于访问子系统中的一组接口,隐藏了系统的复杂性。最简单的应用就是,当controller层的逻辑处…

C#实现二分查找算法

C#实现二分查找算法 以下是一个使用 C# 实现的二分查找算法示例&#xff1a; using System;class Program {static int BinarySearch(int[] arr, int target){int low 0;int high arr.Length - 1;while (low < high){int mid (low high) / 2;// 如果目标值等于中间元素…

doris安装(docker方式)

背景 doris有两个进程 fe,处理用户请求,查询,元数据管理,节点管理be,数据存储,查询计划执行 架构图如下: 参考:https://doris.apache.org/zh-CN/docs/get-starting/what-is-apache-doris 1、定义docker-compose文件 version: 3 services:docker-fe:image: "apac…

MySQL数据库自动备份(Linux操作系统)

方式一 参考&#xff1a;https://blog.csdn.net/qq_48157004/article/details/126683610?spm1001.2014.3001.5506 1.MySQL备份脚本 在/home/backups/下建立.sh文件&#xff0c;文件名称 mysql_backup.sh ,内容如下 #!/bin/bash #备份路径 BACKUP/home/backups/mysqlBackup…

参考线平滑 - FemPosDeviation算法

FemPosDeviation参考线平滑方法是离散点平滑方法 参考文章&#xff1a; &#xff08;1&#xff09;参考线平滑-FemPosDeviation-OSQP &#xff08;2&#xff09;Planning基础库——散点曲线平滑 &#xff08;3&#xff09;参考线平滑-FemPosDeviation-SQP &#xff08;4&#x…

ICCV 2023 | NeRF-Det

NeRF-Det: Learning Geometry-Aware Volumetric Representation for Multi-View 3D Object Detection 介绍 本文介绍了一种新颖的方法&#xff0c;用于仅使用RGB图像作为输入进行室内3D目标检测。作者提出了利用神经辐射场&#xff08;NeRF&#xff09;来显式估计3D几何形状&…

OCP Java17 SE Developers 复习题09

答案 A, E. For the first scenario, the answer needs to implement List because the scenario allows duplicates, narrowing it down to options A and D. Option A is a better answer than option D because LinkedList is both a List and a Queue, and you just nee…

代码随想录 贪心算法-难度题目-其他题目

目录 53.最大子数组和 134.加油站 968.监控二叉树 53.最大子数组和 53. 最大子数组和 中等 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个…

git提交代码描述时如何换行(更新时间24/3/12)

问题复现&#xff08;信心满满使用转义字符换行&#xff09; 解决方法&#xff1a; 写多个-m字符串的结构可以实现自动换行 注意空格 git commit -m"第一行描述" -m"第二行描述" 效果演示&#xff1a;&#xff08;强迫症福利&#xff09;

网络学习:BGP路径属性分类

目录 前言&#xff1a; 路径属性分类 公认必遵 公认任意 可选过渡 可选非过渡 前言&#xff1a; 在默认情况下&#xff0c;到达同一目的地&#xff0c;BGP只走单条路径&#xff0c;并不会在多条路径之间执行负载均衡。对于IGP路由协议&#xff0c;当有多条路径可以到达同…