首页 > 编程语言 >02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流

时间:2023-02-26 19:01:16浏览次数:46  
标签:02 10 字节 int void len new 序列化 读取


第一章 缓冲流

1.1 概述

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_java

  • 为了提高效率

1.2 BufferedOutputStream_字节缓冲输出流

  1. java.io.BufferedOutputStream extends OutputStream
  • BufferedOutputStream:字节缓冲输出流
  1. 继承自父类的共性成员方法:
  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
  • public abstract void write(int b) :将指定的字节输出流。
  1. 构造方法:
  • BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
  1. 参数:
  • OutputStream out:字节输出流
  • 我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
  • int size:指定缓冲流内部缓冲区的大小,不指定默认
  1. 使用步骤【重点】
  1. 创建FileOutputStream对象,构造方法中绑定要输出的目的地
  2. 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率
  3. 使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中
  4. 使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中
  5. 释放资源(会先调用flush方法刷新数据,第4部可以省略)
  • 只用关闭缓冲流
public static void main(String[] args) throws IOException {
//1. ==创建FileOutputStream对象==,构造方法中==绑定要输出的目的地==
FileOutputStream fos = new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\a.txt");
//2. ==创建BufferedOutputStream对象==,构造方法中==传递FileOutputStream对象对象==,提高FileOutputStream对象效率
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3. 使用BufferedOutputStream对象中的方法==write==,把数据写入到内部缓冲区中
bos.write("将数据写入内部缓冲区中".getBytes());
//4. 使用BufferedOutputStream对象中的方法==flush==,把内部缓冲区中的数据,刷新到文件中
bos.flush();
//5. ==释放资源==(会先调用flush方法刷新数据,==第4部可以省略==)
bos.close();
}

1.3 BufferedInputStream_字节缓冲输入流

  1. java.io.BufferedInputStream extends InputStream
  • BufferedInputStream:字节缓冲输入流
  1. 继承自父类的成员方法:
  • int read()从输入流中读取数据的下一个字节。
int len = 0;    //记录每次读取到的字节
while((len = bis.read()) != -1){
System.out.println(len);
}
  • int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int len = 0;    //记录每次读取的有效字节个数
byte[] bytes = new byte[1024]; //存储每次读取的数据
while((len = bis.read(bytes)) != -1){
System.out.println(new String(bytes, 0, len)); //将数组转为字符串,从0开始到len个有效个数
//直接写入时:
//bos.write(bytes, 0, len);
}
  • void close() 关闭此输入流并释放与该流关联的所有系统资源。
  1. 构造方法:
  • BufferedInputStream(InputStream in) 创建一个BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
  • BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
  1. 参数:
  • InputStream in:字节输入流
  • 我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率
  • int size:指定缓冲流内部缓冲区的大小,不指定默认
  1. 使用步骤【重点】:
  1. 创建FileInputStream对象,构造方法中绑定要读取的数据源
  2. 创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
  3. 使用BufferedInputStream对象中的方法read,读取文件
  4. 释放资源
  • 只用关闭缓冲流
public static void main(String[] args) throws IOException {
//1. ==创建FileInputStream对象==,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\a.txt");
//2. ==创建BufferedInputStream对象==,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
BufferedInputStream bis = new BufferedInputStream(fis);
//3. 使用BufferedInputStream对象中的==方法read,读取文件==
//int ==read==()从输入流中读取数据的下一个字节。
/*int len = 0; //记录每次读取到的字节
while((len = bis.read()) != -1){
System.out.println(len);
}*/

//* int ==read==(==byte[] b==)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int len = 0; //记录每次读取的有效字节个数
byte[] bytes = new byte[1024]; //存储每次读取的数据
while((len = bis.read(bytes)) != -1){
System.out.println(new String(bytes, 0, len)); //将数组转为字符串,从0开始到len个有效个数
}


//4. 释放资源
bis.close();
}

1.4 缓冲流的效率测试_复制文件

  1. 文件复制练习:一读一写
  2. 明确:
    数据源: F:\picture\1.jpg
    数据的目的地: E:\picture\1.jpg
  3. 文件复制的步骤:
  1. 创建字节缓冲输入流对象,构造方法中传递字节输入流
  2. 创建字节缓冲输出流对象,构造方法中传递字节输出流
  3. 使用字节缓冲输入流对象中的方法read,读取文件
  • int read()从输入流中读取数据的下一个字节。
  • int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
  1. 使用字节缓冲输出流中的方法write,把读取的数据写入到内部缓冲区中
  2. 释放资源(会先把缓冲区中的数据,刷新到文件中)
  • 先释放写入的
  • 输入流和输出流的结果:(文件的大小:780,831 字节)
  • 一次读写一个字节:6043毫秒
  • 使用数组缓冲读取多个字节,写入多个字节:32毫秒
  • 缓冲输入流和缓冲输出流的结果:(文件的大小:780,831 字节)
  • 一次读写一个字节:32毫秒
  • 使用数组缓冲读取多个字节,写入多个字节:2毫秒
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
//1. 创建字节缓冲输入流对象,构造方法中传递字节输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\picture\\1.jpg"));
//2. 创建字节缓冲输出流对象,构造方法中传递字节输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\picture\\1.jpg"));
//3. 使用字节缓冲输入流对象中的方法read,读取文件
//* int ==read==()从输入流中读取数据的下一个字节。
/*int len = 0; //记录每次读取到的字节
while((len = bis.read()) != -1){
//4. 使用字节缓冲输出流中的方法==write==,把读取的数据写入到内部缓冲区中
bos.write(len);
}*/
//* int ==read==(==byte[] b==)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int len = 0; //记录每次读取的有效字节个数
byte[] bytes = new byte[1024]; //存储每次读取的数据
while((len = bis.read(bytes)) != -1){
//4. 使用字节缓冲输出流中的方法==write==,把读取的数据写入到内部缓冲区中
bos.write(bytes, 0, len);
}


//5. ==释放资源==(会先把缓冲区中的数据,刷新到文件中)
bos.close();
bis.close();
long e = System.currentTimeMillis();
System.out.println("复制文件共耗时:" + (e - s) + "毫秒");
}

1.5 BufferedWriter_字符缓冲输出流(拥有特有方法newLine)

  1. java.io.BufferedWriter extends Writer
  • BufferedWriter:字符缓冲输出流
  1. 继承自父类的共性成员方法:
  • void write(int c) 写入单个字符。
  • void write(char[] cbuf)写入字符数组。
  • abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
  • void write(String str)写入字符串。
  • void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
  • void flush()刷新该流的缓冲。
  • void close() 关闭此流,但要先刷新它。
  1. 构造方法:
  • BufferedWriter(Writer out)创建一个使用默认大小输出缓冲区的缓冲字符输出流。
  • BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
  1. 参数:
  • Writer out:字符输出流
  • 我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率
  • int sz:指定缓冲区的大小,不写默认大小
  1. 特有的成员方法【!】:
  • void newLine():写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符
换行:换行符号
windows:\r\n
linux:/n
mac:/r
  1. 使用步骤:
  1. 创建字符缓冲输出流对象,构造方法中传递字符输出流
  2. 调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
  3. 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源
public static void main(String[] args) throws IOException {
//1. ==创建字符缓冲输出流对象==,==构造方法中传递字符输出流==
BufferedWriter bw = new BufferedWriter(new FileWriter("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\c.txt"));

//2. 调用字符缓冲输出流中的==方法write==,把数据写入到内存缓冲区中
//并用到特有成员方法newLine()来替代换行bw.write("\r\n");
for(int i = 0; i < 10; i++){
bw.write("程序员");
//bw.write("\r\n");
bw.newLine();
}

//3. 调用字符缓冲输出流中的==方法flush==,把内存缓冲区中的数据,刷新到文件中
bw.flush();

//4. ==释放资源==
bw.close();
}

1.6 BufferedReader_字符缓冲输入流(拥有特有方法readLine)

  1. java.io.BufferedReader extends Reader
  • BufferedReader:字符缓冲输入流
  1. 继承自父类的共性成员方法:
  • int read() 读取单个字符并返回。
  • int read(char[] cbuf)一次读取多个字符,将字符读入数组。
  • void close() 关闭该流并释放与之关联的所有资源。
  1. 构造方法:
  • BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。
  • BufferedReader(Reader in, int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。
  1. 参数:
  • Reader in:字符输入流
  • 我们可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高FileReader的读取效率
  1. 特有的成员方法:
  • String readLine() 读取一个文本行。读取一行数据
  • 行的终止符号:通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行(\r\n)。
  • 返回值:
  • 包含该行内容的字符串不包含任何行终止符(需要换行得要自己加【!】),如果已到达流末尾,则返回 null【!】
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
  1. 使用步骤:
  1. 创建字符缓冲输入流对象,构造方法中传递字符输入流
  2. 使用字符缓冲输入流对象中的方法read/readLine读取文本
  3. 释放资源
public static void main(String[] args) throws IOException {
//1. ==创建字符缓冲输入流对象==,==构造方法中传递字符输入流==
BufferedReader br = new BufferedReader(new FileReader("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\c.txt"));

//2. 使用字符缓冲输入流对象中的==方法read/readLine读取文本==
//这里使用readLine
/*String line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);*/
/*
发现以上读取是一个重复的过程,所以可以使用循环优化
不知道文件中有多少行数据,所以使用while循环
while的结束条件,读取到null结束
*/
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}


//3. ==释放资源==
br.close();
}

1.7 练习_对文本的内容进行排序

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_开发语言_02

  1. 练习:
  • 对文本的内容进行排序
  • 按照(1,2,3…)顺序排序
  1. 分析:
  1. 创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,…);value:存储每行的文本
  2. 创建字符缓冲输入流对象,构造方法中绑定字符输入流
  3. 创建字符缓冲输出流对象,构造方法中绑定字符输出流
  4. 使用字符缓冲输入流中的方法readline,逐行读取文本
  5. 对读取到的文本进行切割,获取行中的序号和文本内容
  6. 把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4…)
  7. 遍历HashMap集合,获取每一个键值对
  8. 把每一个键值对,拼接为一个文本行
  9. 把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中
  10. 因为readLine方法不包含任何行终止符,所以需要自己加换行
  11. 释放资源
public static void main(String[] args) throws IOException {
//1. 创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,..);value:存储每行的文本
HashMap<String, String> mapH = new HashMap<>();

//2. 创建字符缓冲输入流对象,构造方法中绑定字符输入流
BufferedReader br = new BufferedReader(new FileReader("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\in.txt"));

//3. 创建字符缓冲输出流对象,构造方法中绑定字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\out.txt"));

//4. 使用字符缓冲输入流中的方法readline,逐行读取文本
String line;
while((line = br.readLine()) != null){
//5. 对读取到的文本进行切割,获取行中的序号和文本内容
String[] arr = line.split("\\."); //返回字符串数组
//6. 把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4..)
mapH.put(arr[0], arr[1]);

}
//7. 遍历HashMap集合,获取每一个键值对
for(String key : mapH.keySet()){
String value = mapH.get(key);
//8. 把每一个键值对,拼接为一个文本行
line = key + "." + value;
//9. 把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中
bw.write(line);
//10. 因为readLine方法不包含任何行终止符,所以需要自己加换行
bw.newLine(); //写换行
}
//11. 释放资源
bw.close();
br.close();
}

第二章 转换流

2.1 字符编码和字符集

  1. 字符编码
  • 编码:字符(能看懂的)–>字节(看不懂的)
  • 解码:字节(看不懂的)–>字符(能看懂的)
  • 字符编码【!】(Character Encoding):就是一套自然语言的字符与二进制数之间的对应规则
  • 编码表:生活中文字和计算机中二进制的对应规则
  1. 字符集
  • 字符集【!】(charset):也叫++编码表++。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
  • 注:当指定了编码,它所对应的字符集自然就指定了

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_java_03


02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_构造方法_04

  • 注:GBK存储中文是2个字节,UTF-8存储中文是3个字节

2.2 编码引出的问题_FileReader读取GBK格式的文件

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_java_05

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\我是GBK格式的文本.txt");

//一次获取多个字节的方式
char[] chars = new char[1024];
int len = 0;
while((len = fr.read(chars)) != -1){
System.out.print(new String(chars, 0, len));
}

fr.close();
}
  • 解决方法:转换流

2.3 转换流的原理

  1. InputStreamReader&FileReader:

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_构造方法_06


2. OutputStreamWriter&FileWriter:

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_java_07

  • 转换流总结【重点】可以指定编码表
  • 可以读取或写入任意编码文件

2.4 OutputStreamWriter介绍&代码实现

  1. java.io.OutputStreamWriter ++extends++ Writer
  • OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)
  1. 继承自父类的共性成员方法:
  • void write(int c):写入单个字符。
  • void write(char[] cbuf):写入字符数组。
  • abstract void write(char[] cbuf, int off, int len):写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
  • void write(String str):写入字符串。
  • void write(String str, int off, int len):写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
  • void flush():刷新该流的缓冲。
  • void close():关闭此流,但要先刷新它。
  1. 构造方法:
  • OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, String charsetName):创建使用指定字符集的 OutputStreamWriter。
  1. 参数:
  • OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
  • String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,…不指定默认使用UTF-8
  • 带双引号,因为是String类型
  1. 使用步骤【重点】:
  1. 创建OutputStreamWriter对象,构造方法传递字节输出流和指定的编码表名称
  2. 使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
  3. 使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
  4. 释放资源
public class Demo02OutputStreamWriter {
public static void main(String[] args) throws IOException {
//write_utf_8();
write_gbk();
}

//使用转换流OutputStreamWriter写GBK的文件
private static void write_gbk() throws IOException {
//1. 创建==OutputStreamWriter对象==,==构造方法==中==传递字节输出流和指定的编码表名称==
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\gbk.txt"), "GBK");
//2. 使用OutputStreamWriter对象中的方法==write==,把字符转换为字节存储缓冲区中(==编码==)
osw.write("你好");
//3. 使用OutputStreamWriter对象中的方法==flush==,把内存缓冲区中的字节刷新到文件中(==使用字节流写字节的过程==)
osw.flush();
//释放资源
osw.close();
}

//使用转换流OutputStreamWriter写UTF-8的文件
private static void write_utf_8() throws IOException {
//1. 创建==OutputStreamWriter对象==,==构造方法==中==传递字节输出流和指定的编码表名称==
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\utf_8.txt"), "utf-8");
//不指定默认也是UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\utf_8.txt"));
//2. 使用OutputStreamWriter对象中的方法==write==,把字符转换为字节存储缓冲区中(==编码==)
osw.write("你好");
//3. 使用OutputStreamWriter对象中的方法==flush==,把内存缓冲区中的字节刷新到文件中(==使用字节流写字节的过程==)
osw.flush();
//释放资源
osw.close();
}
}

2.5 InputStreamReader介绍&代码实现

  1. java.io.InputStreamReader extends Reader
  • InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)
  1. 继承自父类的共性成员方法:
  • int read():读取单个字符并返回。
  • int read(char[] cbuf):一次读取多个字符,将字符读入数组。
  • void close():关闭该流并释放与之关联的所有资源。
  1. 构造方法:
  • InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。
  • InputStreamReader(InputStream in, String charsetName):创建使用指定字符集的 InputStreamReader。
  1. 参数:
  • InputStream in:字节输入流,用来读取文件中保存的字节
  • StringcharsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,…不指定默认使用UTF-8
  1. 使用步骤【重点】:
  1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
  2. 使用InputStreamReader对象中的方法read读取文件
  3. 释放资源
  1. 注意事项【重点】:
    构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码
public class Demo03InputStreamReader {
public static void main(String[] args) throws IOException {
//read_utf_8();
read_gbk();
}

//使用转换流InputStreamReader读取GBK的文件
private static void read_gbk() throws IOException {
//1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
InputStreamReader isr = new InputStreamReader(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\gbk.txt"), "GBK");
//InputStreamReader isr = new InputStreamReader(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\gbk.txt"), "UTF-8"); //乱码
//2. 使用InputStreamReader对象中的方法read读取文件
//一次读取多个的方式
char[] chars = new char[1024];
int len = 0;
while((len = isr.read(chars)) != -1){
System.out.print(new String(chars, 0, len));
}
//一次去一个字节的方式
/*int len = 0;
while((len = isr.read()) != -1){
System.out.print((char)len);
}*/
//3. 释放资源
isr.close();
}

//使用转换流InputStreamReader读取UTF-8的文件
private static void read_utf_8() throws IOException {
//1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
//InputStreamReader isr = new InputStreamReader(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\utf_8.txt"), "UTF-8");
//默认格式UTF-8
InputStreamReader isr = new InputStreamReader(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\utf_8.txt"));
//2. 使用InputStreamReader对象中的方法read读取文件
//一次读取多个的方式
/*char[] chars = new char[1024];
int len = 0;
while((len = isr.read(chars)) != -1){
System.out.print(new String(chars, 0, len));
}*/
//一次去一个字节的方式
int len = 0;
while((len = isr.read()) != -1){
System.out.print((char)len);
}
//3. 释放资源
isr.close();
}
}

2.6 练习:转换文件编码

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_开发语言_08

  1. 练习:转换文件编码(就读取最开始创建的:我是GBK格式的文本)
  • 将GBK编码的文本文件,转换为UTF-8编码的文本文件。
  1. 分析:
  1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
  2. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
  3. 使用InputStreamReader对象中的方法read读取文件
  4. 使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
  5. 释放资源
public static void main(String[] args) throws IOException {
//1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\我是GBK格式的文本.txt"), "GBK");
//2. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\我是UTF-8格式的文本.txt"), "UTF-8");
//3. 使用InputStreamReader对象中的方法read读取文件
/*char[] chars = new char[1024];
int len = 0;
while((len = isr.read(chars)) != -1){
//4. 使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
osw.write(chars, 0, len);
}*/
int len = 0;
while ((len = isr.read()) != -1){
//4. 使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
osw.write(len);
}
//5. 释放资源
osw.close();
isr.close();
}

第三章 序列化流

3.1序列化和反序列化的概述

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_输入流_09


02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_java_10

3.2对象的序列化流_ObjectOutputStream(特有方法writeObject)

  1. java.io.ObjectOutputStream extends OutputStream
  • ObjectOutputStream:对象的序列化流
    作用:把对象以流的方式写入到文件中保存
  1. 构造方法:
  • ObjectOutputStream(OutputStream out):创建写入指定OutputStream 的 ObjectOutputStream。
  1. 参数:
  • OutputStream out:字节输出流
  1. 特有的成员方法:
  • void writeObject(Object obj):将指定的对象写入 ObjectOutputStream。
  1. 使用步骤:
  1. 创建ObjectOutputStream对象,构造方法中传递字节输出流
  2. 使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
  3. 释放资源
  1. 执行上面步骤会出现的异常【重点】–>类实现Serializable接口
  1. 序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常
  2. 类通过实现java.io.Serializable接口以启用其序列化功能,未实现此接口的类将无法使其任何状态序列化或反序列化。
  3. Serializable接口也叫标记型接口(接口中什么都没有)
  • 要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记
  • 当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记
  • 有:就可以序列化和反序列化
  • 没有:就会抛出 NotSerializableException异常
  • 去市场买肉–>肉上有一个蓝色章(检测合格)–>放心购买–>买回来怎么吃随意
  1. 序列化的前提【重点】:
  1. 类必须实现Serializable
//定义一个Person类
import java.io.Serializable;

public class Person implements Serializable {
private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}
//主方法:Demo01ObjectOutputStream.java
public static void main(String[] args) throws IOException {
//1. ==创建ObjectOutputStream对象==,==构造方法中传递字节输出流==
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\Person.txt"));
//2. 使用ObjectOutputStream对象中的==方法writeObject==,==把对象写入到文件中==
oos.writeObject(new Person("小美女", 18));
//3. 释放资源
oos.close();
}

//结果是将对象以二进制方式存储

3.3 对象的反序列化流_ObjectInputStream(特有成员方法readObject)

  1. java.io.ObjectInputStream extends InputStream
  • ObjectInputStream:对象的反序列化流
  1. 作用:把文件中保存的对象,以流的方式读取出来使用
  2. 构造方法:
  • ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
  1. 参数:
  • InputStream in:字节输入流
  1. 特有的成员方法:
  • ObjectreadObject() 从 ObjectInputStream 读取对象。
  1. 使用步骤【重点】:
  1. 创建ObjectInputStream对象,构造方法中传递字节输入流
  2. 使用ObjectInputStream对象中的方法readObject读取保存对象的文件
  3. 释放资源
  4. 使用读取出来的对象(打印)
  1. readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)–>该异常不属于IO异常
  • 当不存在对象的class文件时抛出此异常
  1. 反序列化的前提【重点】:
  1. 类必须实现Serializable
  2. 必须存在类对应的class文件
//定义一个Person类:Person.java
import java.io.Serializable;

public class Person implements Serializable {
private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}
//主方法:Demo02ObjectInputStream.java
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1. ==创建ObjectInputStream对象==,==构造方法中传递字节输入流==
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\Person.txt"));
//2. 使用ObjectInputStream对象中的==方法readObject读取保存对象的文件==
Object o = ois.readObject();
//3. ==释放资源==
ois.close();
//4. ==使用读取出来的对象(打印)==
System.out.println(o);
//转换为Person类型
Person p = (Person)o;
System.out.println(p.getName() + "=" + p.getAge());
}

//结果:(将3.2Person中存储的内容读取出来)
Person{name='小美女', age=18}
小美女+18

3.4 transient关键字_瞬态关键字

  1. static关键字:静态关键字
  • 静态优先于非静态加载到内存中(静态优先于对象进入到内存中)
  • 被static修饰的成员变量不能被序列化的,序列化的都是对象
private static int age;
oos.writeObject(new Person("小美女",18));
Object o = ois.readObject();
Person{name='小美女', age=0}
  1. transient关键字:瞬态关键字
  • 被transient修饰成员变量,不能被序列化
private transient int age;
oos.writeObject(new Person("小美女",18));
Object o = ois.readObject();
Person{name='小美女', age=0}
  1. 作用:
  • 不想让某个成员变量序列化时候使用

3.5 InvalidClassException异常_原理和解决方案

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_输入流_11

  • 解决方法:
  • 在类中手动加一个序列号
  • 这样修改为public后序列号不会进行更改,直接反序列化可以出来值
static final long serialVersionUID = 1L;

3.6 练习_序列化集合

02_10_Java语音进阶||day10_缓冲流、转换流、序列化流、打印流_输出流_12

  1. 练习:序列化集合
  • ++当我们想在文件中保存多个对象的时候++
  • 可以把多个对象存储到一个集合中
  • 对集合进序列化和反序列化
  1. 分析:
  1. 定义一个存储Person对象的ArrayList集合
  2. 往ArrayList集合中存储Person对象
  3. 创建一个序列化流ObjectOutputStream对象
  4. 使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化
  5. 创建一个反序列化ObjectInputStream对象
  6. 使用ObjectInputStream对象中的方法readObject读取文件中保存的集合
  7. 把Object类型的集合转换为ArrayList类型
ArrayList<Person> listA2 = (ArrayList<Person>)o;
  1. 遍历ArrayList集合
  2. 释放资源
//定义一个对象:Person.java
import java.io.Serializable;

public class Person implements Serializable {
static final long serialVersionUID = 1L;
private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

//主方法:Demo03Test.java
import java.io.*;
import java.util.ArrayList;

public class Demo03Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1. 定义一个存储Person对象的ArrayList集合
ArrayList<Person> listA = new ArrayList<>();
//2. 往ArrayList集合中存储Person对象
listA.add(new Person("张三", 18));
listA.add(new Person("李四", 30));
listA.add(new Person("王五", 43));
//3. 创建一个序列化流ObjectOutputStream对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\list.txt"));
//4. 使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化
oos.writeObject(listA);
//5. 创建一个反序列化ObjectInputStream对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\list.txt"));
//6. 使用ObjectInputStream对象中的方法readObject读取文件中保存的集合
Object o = ois.readObject();
//7. 把Object类型的集合转换为ArrayList类型
ArrayList<Person> listA2 = (ArrayList<Person>)o;
//8. 遍历ArrayList集合
for (Person p : listA2) {
System.out.println(p);
}
//9. 释放资源
ois.close();
oos.close();
}
}

//结果:
Person{name='张三', age=18}
Person{name='李四', age=30}
Person{name='王五', age=43}

第四章 打印流

4.1 打印流_概述和使用(特有的方法,print,println)

  1. 概述
  2. java.io.PrintStream:打印流
  • PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
  1. PrintStream特点:
  1. 只负责数据的输出,不负责数据的读取
  2. 与其他输出流不同,PrintStream 永远不会抛出 IOException
  • 但是会抛出文件找不到异常FileNotFoundException
  1. 有特有的方法,print,println
  • void print(任意类型的值)
  • void println(任意类型的值并换行)
  1. 构造方法:
  • PrintStream(File file):输出的目的地是一个文件
  • PrintStream(OutputStream out):输出的目的地是一个字节输出流
  • PrintStream(String fileName) :输出的目的地是一个文件路径
  1. PrintStream extends OutputStream 继承自父类的成员方法:
  • public void close():关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len):从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
  • public abstract void write(int b):将指定的字节输出流。
  1. 使用步骤【重点】
  1. 创建打印流PrintStream对象,构造方法中绑定要输出的目的地
  2. 使用继承自父类的write方法写数据或者使用自己特有的方法print/println方法写数据
  3. 释放资源
  1. 注意:
  • 如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->a
  • 如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97
public static void main(String[] args) throws FileNotFoundException {
//创建打印流PrintStream对象,构造方法中绑定要输出的目的地
PrintStream ps = new PrintStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\print.txt");
//使用继承自父类的write方法写数据-->a
ps.write(97);
//使用自己特有的方法print/println方法写数据-->97
ps.println(97);
ps.print(97);


//释放资源
ps.close();
}

//结果:
a97
97
  1. 特点:
  • 可以改变输出语句的目的地(打印流的流向)
  • 输出语句,默认在控制台输出
  • 使用System.setOut方法,改变输出语句的目的地++改为++参数中传递的打印流的目的地
  • static void setOut(PrintStream out)
  • 重新分配“标准”输出流。
import java.io.FileNotFoundException;
import java.io.PrintStream;

public class Demo02PrintStream {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("我是控制台输出");

PrintStream ps = new PrintStream("Dark-horse-teaching\\src\\cn\\javaadvance\\day10\\目的地是打印流.txt");
System.setOut(ps); //把输出语句的目的地改变为打印流的目的地
System.out.println("我在打印流的目的地中输出");

ps.close();
}
}

//结果:控制台中
我是控制台输出

//结果:目的地是打印流.txt文件中
我在打印流的目的地中输出


标签:02,10,字节,int,void,len,new,序列化,读取
From: https://blog.51cto.com/u_15980166/6086816

相关文章

  • 02_07_Java语音进阶||day07_等待与唤醒案例、线程池、Lambda表达式
    第一章等待唤醒机制1.1线程间通信概念:多个线程在处理同一个资源(包子),但是处理的动作(线程的任务)却不相同。比如:线程A用来生产包子的,线程B用来吃包子的,包子可以理解......
  • 02_06_Java语音进阶||day06_线程、同步、线程状态
    第一章线程1.1多线程原理-执行流程1.2多线程原理-内存图解多线程的好处:多个线程之间互不影响(在不同的栈空间)1.3Thread类常用方法_获取线程名称的方法获取线程的名称两种......
  • 02_03_Java语音进阶||day03_数据结构(集合相关)、List、Set、可变参数、Collections工具
    第一章数据结构1.1数据结构的作用Java是面向对象的语音,好似自动挡汽车,c语音手动挡,数据结构?数据结构:是变速箱的工作原理。你完全可以不懂变速箱怎样工作,就可以把自动挡车从......
  • 浅谈VastbaseG100-产品介绍
    一、产品介绍VastbaseG100数据库是“北京海量数据技术股份有限公司”基于开源opengauss内核开发的企业级关系型数据库。除了具有opengauss的极致性能、同时在原有的基础......
  • 免费领取2023年上半年信息系统项目管理师重要知识点10G资料包
    课课家软考学院为2023年上半年信息系统项目管理师考生整理了2023年上半年信息系统项目管理师重要知识点10G学习资料的内容,希望能帮助考生掌握信息系统项目管理师的重要......
  • Django 框架基础10:模版(T)Django模版引擎、Jinja2模版引擎
    Django自带模版<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body>Hello,{{username}}!<p>我没有定义的......
  • 数据挖掘2023.2.26
    #代码3-3捞起生鱼片的季度销售情况importpandasaspdimportnumpyasnpcatering_sale='D:/develop/Spider/data/catering_fish_congee.xls'#餐饮数据data=pd.r......
  • 2023.2.26
    #-*-coding:utf-8-*-"""CreatedonWedFeb2210:56:392023@author:admin"""importpandasaspdcatering_sale='C:\\Users\\ASUS\\Documents\\WeChatFiles\\wx......
  • 【闲话】2023.2.26
    我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可爱!我好可......
  • U盘重装win10系统
    一、下载微PE工具箱微PE工具箱-超好用的装机维护工具(wepe.com.cn)1.下载微PE工具箱,安装到U盘 2.勾选上包含DOS工具箱 二、下载win10iso文件到U盘msdn我告诉......