day012 IO【转换流、打印流、序列化】

1 字符流

1.1 字符编码表

编码表就是字节(数字)和字符(汉字或者其他语言)的对应关系表。

 

ASCII:                   1字节(0 + 7个二进制位)     128个字符

iso8859-1(latin)     1字节                                       256个字符。

gb2312(1980)             1/2 个字节                              包含了六千多中文或者符号。

big5                       1/2 个字节                              支持繁体字。

gbk                       1/2 字节                                  支持两万多的汉字以及字符。

unicode:国际标准码表。 可以表示任何国家的任何语言,并且任何字符都采用两个字节去存储。 unicode8.0 甚至支持emoji。

 

UTF-8:万国码

 

UTF-32: 采用4个字节去存储。

UTF-16:采用2/3/4个字节去存储。

UTF-8: 采用1/2/3/4个字节去存储。

 

只需要知道两个。

gbk: 中文在gbk中占2个字节。

utf-8: 中文在utf-8中占3个

 

文字--->(数字) :编码:就是看能看懂内容,转换成看不懂的内容。

(数字)--->文字  : 解码: 就是把看不懂的内容,转换成看懂的内容。

 

1.2 io分类回顾

QQ截图20201201100344.png

2 转换流

2.1 转换流写入和读取的工作流程

QQ截图20201203084939.png

2.2 OutputStreamWriter

OutputStreamWriter 是转换流。 是字符通向字节的桥梁。

可以指定编码集进行写入。

构造方法:

OutputStreamWriter(OutputStream out): 需要传递一个字节输出流。   采用默认编码方式进行写入。

OutputStreamWriter(OutputStream out, String charsetName):  第一个参数为字节输出流,第二个参数为编码集名称。 可以指定编码集进行写入。

写入方法。

写入方法,和之前字符流的写入方法是一样的。因为OutputStreamWriter属于字符流。

注意:

转换流本身并不具备读或者写的功能,它的作用是查询码表进行转码。

读或者写真正是由字节流做的

 

指定的编码集必须要存在,如果不存在就会报错

ANSI 在windows指的就是gbk。

2.3 OutputStreamReader

InputStreamReader 也是转换流。 字节通向字符的桥梁。 

这个流可以指定编码进行读取。

 

构造方法:

InputStreamReader(InputStream in):传递一个字节输入流。 以默认编码方式进行读取。

InputStreamReader(InputStream in, String charsetName): 第一个是字节输入流。第二个是指定的编码方式。可以指定编码进行读取。

读取的方法:

通过转换流读取。 以字符为单位。 因为转换流属于字符流的一种。

注意:代码中是以字符为单位读的。但是内部会使用InputStream字节输入流,以字节为单位读取。

注意:

转换流本身并不具备读或者写的功能。它的作用查询码表进行转码。

数据其实真正是由字节流读或者写的。

 

文件是使用哪种编码存储,那么读取的时候就要指定哪种编码,否则就会出现乱码。

转换流作用:

可以指定编码集进行读写。

2.4 InputStreamReader

InputStreamReader 也是转换流。 字节通向字符的桥梁。  

这个流可以指定编码进行读取。

 

构造方法

InputStreamReader(InputStream in):传递一个字节输入流。 以默认编码方式进行读取。

InputStreamReader(InputStream in, String charsetName): 第一个是字节输入流。第二个是指定的编码方式。可以指定编码进行读取。

 

读取的方法:

 通过转换流读取。 以字符为单位。 因为转换流属于字符流的一种。

 注意:代码中是以字符为单位读的。但是内部会使用InputStream字节输入流,以字节为单位读取。

 

注意:

 转换流本身并不具备读或者写的功能。它的作用查询码表进行转码。

 数据其实真正是由字节流读或者写的。

 

       文件是使用哪种编码存储,那么读取的时候就要指定哪种编码,否则就会出现乱码。

 

 

转换流作用:

 可以指定编码集进行读写。

2.4 转换流和子类的区别

字符流的继承体系。

 

字符输出流:

Writer: 是顶层父类。 是一个抽象类。

 |-- OutputStreamWriter: 转换流,可以指定编码方式进行写入。

  |-- FileWriter: 是以默认的编码方式进行写入。 是父类的一个更简单的用法。

   

字符输入流:

Reader: 顶层父类,是一个抽象类。

 |-- InputStreamReader:转换流,可以指定编码进行读取。

  |-- FileReader: 是以默认编码进行读取。 是父类更简单的写法。

   

总结:以下三种写法是一样的

 使用转换流指定一个编码方式,这个指定的编码方式为gbk。

 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file03.txt"), "gbk");

 

 使用转换流,不指定编码方式,会采用的默认的gbk。

 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file03.txt"));

 

 使用子类FileWriter,采用的就是默认的gbk。

 FileWriter fw = new FileWriter("file03.txt");

3 序列化流

QQ拼音截图未命名.png

3.1 ObjectOutputStream 序列化流

 

ObjectOutputStream 叫做序列化流,可以将java程序中的对象写入到文件中。

 

构造方法:

             ObjectOutputStream(OutputStream out): 传递一个字节输出流对象。

 

其他方法:

void writeObject(Object obj):向文件中写入一个对象。

 

要写入的对象必须实现一个接口。这个接口叫做Serializable,如果没有实现这个接口,就会引发NotSerializableException

 

写入进去的内容我们是看不懂,因为它不是给我们看的。

 

3.2 ObjectInputStream 反序列化流

ObjectInputStream叫做反序列化流, 用来从文件中读取对象。

构造方法

 ObjectInputStream(InputStream in): 传递一个字节输入流

 

读取对象的方法:

 Object readObject(): 读取对象

 

注意:如果读取对象的时候,这个对象的class文件不存在,就会引发ClassNotFoundException。

 

如果想要写入多个对象,可以把这些对象放入到一个集合中,然后把集合写入到文件,最终再读取。

 

3.3 Serializable接口

Serializable 是序列化接口,一个类的对象想要被序列化,必须要实现这个接口。

这个接口中没有任何方法,它的作用只是做一个标记,实现这个接口的类的对象才能够被序列化。

 

3.4 注意

1. 被static修饰的成员,不会被序列化。

2. 如果希望某个对象的成员变量在序列化的时候不要写入到文件中,同时也不希望使用static。

          可以使用另外一个关键字,这个关键字叫做transient。

          transient 表示瞬态,被transient修饰的属性不会被序列化。

3.5 版本号冲突问题及解决方法

QQ截图20201222233207.png

 

 

如果向文件中写入一个对象后,对这个对象所在的类进行修改,然后再读取就会引发异常。

原因是因为读取前和读取后的版本号(序列化)不一致

 

如何解决?

可以给这个类分配一个固定的版本号,这样这个类无论怎么修改,这个版本号都不会变。

 

如何给这个类分配一个固定的版本号?

直接在这个类中给出一个静态常量,叫做serialVersionUID。 这个静态常量表示的就是版本号(序列化)的意思

 

4 打印流

特点:

 1. 只有输出,没有输入(只能写,不能读)

 2. 使用比较方便。

 

PrintWriter(字符打印流):

 构造方法:

  PrintWriter(File file)  

  PrintWriter(OutputStream out)

  PrintWriter(String fileName)  

  PrintWriter(Writer out)

PrintStream(字节打印流):

 构造方法:

  PrintStream(File file)

  PrintStream(OutputStream out)

  PrintStream(String fileName)  

   

打印流里面写入的方法。

 write: 如果写入的是数字,会查询ASCII码最终写入这个数字对应的字符。

 print: 如果写入的是数字,会原样写入到文件中。写入之后不会换行。

 println:写入之后会自动换行。

 

使用步骤:

 1. 创建打印流对象

 2. 调用方法,进行写入。

 3. 释放资源

 

打印流的自动刷新

字符输出流写数据的时候需要刷新。

字节流写的时候不需要刷新

 

自动刷新的要求

1. 输出目标必须是流;

 PrintWriter(OutputStream out, boolean autoFlush)

 PrintWriter(Writer out, boolean autoFlush)

2. 第二的构造参数指定为true;

3. 必须调用println、printf或format之一才会生效。

 

5 Commons-IO 等第三方工具的使用

什么是第三方?

 第一方: Oracle官方。

 第二方: 程序员自己。

 第三方: 除此之外全部都是第三方。

 

后期用的东西大多都是由第三方提供的工具。

这些工具都会以jar包的形式给你。

jar包就是一种压缩包。里面放的都是.class文件。

 

现在我们学的这个工具叫做commons-io,他也是第三方工具,也是也jar包的形式提供的,它对应的jar包是 commons-io-2.6.jar

 

commons-io 是由Apache(阿帕奇)提供的一个第三方工具,作用是简化了我们对IO流的操作。

Apache是 美国开源基金组织。

后期很多框架或者其他工具都是由apache维护或者提供的。

比如: tomcat。 active-mq。 struts2。 haddop,commons-io

 

 

 

如果要使用第三方工具,必须要进行导jar包。(重要)

步骤:

 1. 在当前项目下新建文件夹,叫做lib

 2. 把要导入的jar包拷贝到这个lib文件夹下。  

 3. 点击jar包 -> 右键 -> build path -> add to build path

 

在commons-io中,有一个工具类,可以完成很多功能,这个类叫做FileUtils

里面的方法

static void writeStringToFile(File file, String data):向文件中写入字符串。

static String readFileToString(File file):读取文件,并返回字符串。

static void copyFile(File srcFile, File destFile): 复制文件。srcFile源文件。destFile目标文件

static void copyDirectoryToDirectory(File srcDir, File destDir): 复制文件夹。

 

@Deprecated //这个东西叫做注解,这个注解的作用表示这个东西已经过时了,被用这个注解的方法,使用时方法就会被划上横线。

 

5.1 关联源码

    按住Ctrl点方法,然后点Attach Source...,然后点External location,然后如果源码是以文件形式提供的就选External File,如果源码是以文件夹形式提供的,就选External Folder。

 

5 NIO介绍

BIO:同步阻塞IO

NIO:同步非阻塞IO。netty,dubbo

在指定IO操作的时候,可以去做其他事情。

NIO是基于 缓冲区, 通道,选择器。

AIO:异步非阻塞IO

 

阻塞指的是线程阻塞,线程在阻塞的时候就不能干其他事情了。

阻塞:看成去银行排队取钱,一直ATM前面排队。

非阻塞:去柜台拿个号,然后等着取钱,等着的时候,可以干别的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
枚举类型是一个有限的取值集合,可以通过序列化和反序列化将其转换为字符串或数字。 序列化:将枚举类型转换为字符串或数字,以便于存储或传输。在C#中,可以使用Enum.ToString()方法将枚举转换为字符串,也可以使用(Enum)枚举值将枚举转换为整数。 反序列化:将字符串或数字转换为枚举类型。在C#中,可以使用Enum.Parse()方法将字符串转换为枚举类型,也可以使用(Enum)整数将整数转换为枚举类型。 以下是一个示例代码: ```csharp using System; enum DayOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } class Program { static void Main(string[] args) { // 序列化 DayOfWeek day = DayOfWeek.Monday; string dayStr = day.ToString(); int dayInt = (int)day; Console.WriteLine($"dayStr: {dayStr}"); Console.WriteLine($"dayInt: {dayInt}"); // 反序列化 string dayStr2 = "Wednesday"; DayOfWeek day2 = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), dayStr2); int dayInt2 = 5; DayOfWeek day3 = (DayOfWeek)dayInt2; Console.WriteLine($"day2: {day2}"); Console.WriteLine($"day3: {day3}"); } } ``` 输出结果: ``` dayStr: Monday dayInt: 1 day2: Wednesday day3: Friday ``` 在上面的示例中,我们首先将枚举类型`DayOfWeek`的值序列化为字符串和整数,然后将其反序列化为枚举类型的值。注意,反序列化时需要使用`Enum.Parse()`方法将字符串转换为枚举类型,或者使用强制类型转换将整数转换为枚举类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值