文章整理时候比较仓促
3.字符流
3.字符流
用来处理用记事本打开自己能看得懂的那些文件
由于字节流操作中文不是特别的方便,所以ava就提供字符流
- 字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
- 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
4.编码表
基础知识:
-
计算机中储存的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
-
按照某种规则,将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调一下:按照A编码存储,必须按照A编码解析,这样才能显示正确的文本符号。否则就会导致乱码现象
字符编码:就是一套自然语言的字符与二进制数之间的对应规则(A65)公
字符集
- 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
- 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。
常见字符集有ASClI字符集、GBXXX字符集、Unicode字符集等
ASCLL字符集:
- ASClI(American Standard Code for Information Interchange,美国信息交换标准代码):是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
- 基本的ASCl字符集,使用7位表示一个字符,共128字符。ASCI的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图
GBXXX字符集:
- GB2312:简体中文码表。一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名等都编进去了,连在ASC里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的“全角“字符,而原来在127号以下的那些就叫“半角“字符了
- GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以日韩汉字等
- GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等
Unicode字符集:
- 为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF32。最为常用的UTF-8编码
- UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
128个US-ASCI字符,只需一个字节编码拉
丁文等字符,需要二个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字爷编码
采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
5.字符串中编码解码问题
编码:
- byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
- byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码:
- String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
- String(byte[] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
package com.study_01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
// FileInputStream fis = new FileInputStream("a.txt");
//
// int by;
// while((by = fis.read()) != -1){
// System.out.print((char) by);
// }
//
// fis.close();
// String s = "abc";
String s = "中国"; // [-28, -72, -83, -27, -101, -67]
// byte[] bys = s.getBytes(); // [-28, -72, -83, -27, -101, -67]
// byte[] bys = s.getBytes(StandardCharsets.UTF_8); // [-28, -72, -83, -27, -101, -67]
byte[] bys = s.getBytes("GBK"); // [-42, -48, -71, -6]
System.out.println(Arrays.toString(bys));
}
}
package com.study_01;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "中国";
// 编码 平台默认UTF-8
// byte[] bys = s.getBytes(); // [-28, -72, -83, -27, -101, -67]
// byte[] bys = s.getBytes("UTF-8"); // [-28, -72, -83, -27, -101, -67]
byte[] bys = s.getBytes("GBK"); // [-42, -48, -71, -6]
System.out.println(Arrays.toString(bys));
// 解码 平台默认UTF-8
// String ss = new String(bys);
// String ss = new String(bys,"UTF-8");
String ss = new String(bys,"GBK");
System.out.println(ss);
}
}
6.字符流中编码解码问题
字符流抽象基类
- Reader:字符输入流的抽象类
- Writer:字符输出流的抽象类
字符流中和编码解码问题相关的两个类:
- InputStreamReader
- OutputStreamWriter
7.字符流写数据的五种方式
package com.study_02;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/*
写数据的5种方式:
void write(int c):写一个字符
void write(char[] cbuf):写入一个字符数组
void write(char[] cbuf,int off,int Len):写入字符数组的一部分
void write(String str):写一个字符串
void write(String str,int off,int Len):写一个字符串的一部分
*/
public class OutpuStreamWriterDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
// 1 void write(int c):写一个字符
// osw.write(97);
// // void flush() 刷新流
// osw.flush();
// osw.write(98);
// osw.flush();
// 2 void write(char[]cbuf):写入一个字符数组
char[] chs = {'a','b','c','e'};
// osw.write(chs);
// 3 void write(char[]cbuf,int off,int Len):写入字符数组的一部分
// osw.write(chs,1,3);
// 4 void write(String str):写一个字符串
// osw.write("abvdes");
// 5 void write(String str,int off,int Len):写一个字符串的一部分
// osw.write("abcde",0,"abcde".length());
osw.write("abcde",1,3);
// 释放资源
osw.close();
}
}
8.字符流读数据两种方式
package com.study_02;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class IntputStreamReaderDemo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));
// 1
// int ch;
// while ((ch = isr.read()) != -1) {
// System.out.print((char) ch);
// }
// 2
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1) {
System.out.println(new String(chs,0,len));
}
// 释放资源
isr.close();
}
}
9.字符流复制Java文件
package com.study_03;
import java.io.*;
public class CopyJavaDemo01 {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("ConversionStreamDemo.java"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Copy01.java"));
// // 一次读取一个字符
// int ch;
// while ((ch = isr.read())!=-1) {
// osw.write(ch);
// }
// isr.close();
// osw.close();
// 一次读取一个字符数组数据
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs))!=-1) {
osw.write(chs,0,len);
}
isr.close();
osw.close();
}
}
10.复制改进
需求:把模块目录下的“ConversionStreamDemo,java”复制到模块目录下的“Copy.java"
分析:
①转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类
②FileReader:用于读取字符文件的便捷类
FileReader(String fileName)
③FileWriter:用于写入字符文件的便捷类
FileWriter(String fileName)
④数据源和目的地的分析
数据源:myCharStream\ConversionStreamDemo,java—读数据—Reader—InputStreamReader—FileReader目的地:
myCharStream\Copy.java—写数据—Writer—OutputStreamWriter—FileWriter
package com.study_03;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyJavaDemo02 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("ConversionStreamDemo.java");
FileWriter fw = new FileWriter("Copy.java");
// int ch;
// while ((ch=fr.read())!=-1) {
// fw.write(ch);
// }
char[] chs = new char[1024];
int len;
while ((len = fr.read(chs))!=-1) {
fw.write(new String(chs,0,len));
}
fr.close();
fw.close();
}
}
11.字符缓冲流
字符缓冲流:
- BufferedWriter:将文本写入字符输出流,缓中字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
- BufferedReader:从字符输入流读取文本,缓中字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途
构造方法:
- BufferedWriter(Writer out)
- BufferedReader(Reader in)
package com.study_04;
import java.io.*;
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("bw.txt");
BufferedWriter bw = new BufferedWriter(fw);
// BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
//
// bw.write("hello\r\n");
// bw.write("hello\r\n");
// bw.close();
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
// 1
// int ch;
// while ((ch = br.read())!=-1) {
// System.out.print((char) ch);
// }
// 2
char[] chs = new char[1024];
int len;
while ((len = br.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
br.close();
}
}
12.字符缓冲流复制Java文件
package com.study_04;
import java.io.*;
public class CopyJavaDemo01 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("CopyBuffer01.java"));
// 一次读一个字符数据
// int ch;
// while ((ch = br.read())!=-1) {
// bw.write(ch);
// }
// 一次读写一个数组的数据
char[] chs = new char[1024];
int len;
while ((len = br.read(chs))!=-1) {
bw.write(chs,0,len);
}
br.close();
bw.close();
}
}
13.字符缓冲流特有的功能
BufferedWriter:
- void newLine():写一行行分隔符,行分隔符字符串由系统属性定义后
BufferedReader:
- public String readLine():读一行文字。结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null
package com.study_04;
import java.io.*;
import java.nio.Buffer;
public class BufferedStreamDemo02 {
public static void main(String[] args) throws IOException {
// BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
for (int i = 0; i < 10; i++) {
bw.write("hello"+i);
bw.newLine();
bw.flush();
}
bw.close();
BufferedReader br = new BufferedReader((new FileReader("bw.txt")));
// String readLine = br.readLine();
// System.out.println(readLine);
//
// readLine = br.readLine();
// System.out.println(readLine);
//
// readLine = br.readLine();
// System.out.println(readLine);
String line;
while ((line = br.readLine())!=null) {
System.out.println(line);
}
br.close();
}
}
14.字符缓冲流复制Java文件
package com.study_04;
import java.io.*;
public class CopyJavaDemo02 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("CopyBuffer02.java"));
String line;
while ((line = br.readLine())!=null) {
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
}
}
15.IO流小结
16.集合到文件
需求:把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据
package com.study_05;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
public class ArrayListToTxtDemo {
public static void main(String[] args) throws IOException {
// 创建arraylist集合
ArrayList<String> arrayList = new ArrayList<>();
// 忘集合中存储字符串元素
arrayList.add("hello");
arrayList.add("world");
arrayList.add("java");
0
BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));
for (String s : arrayList) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}
17.文件到集合
需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个集合元素
package com.study_05;
import java.io.*;
import java.util.ArrayList;
public class TxtToArrayistListDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("array.txt"));
ArrayList<String> array = new ArrayList<>();
String line;
while ((line = br.readLine())!=null) {
array.add(line);
}
br.close();
for (String s :
array) {
System.out.println(s);
}
// System.out.println(array);
}
}
18.点名器
需求:我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随机点名器
package com.study_05;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class CallNameDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("names.txt"));
ArrayList<String> array = new ArrayList<>();
String line;
while ((line = br.readLine())!=null) {
array.add(line);
}
br.close();
Random r = new Random();
int index = r.nextInt(array.size());
String name = array.get(index);
System.out.println(name);
}
}
19.集合到文件改进版
package com.study_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class ArrayListToFileDemo {
public static void main(String[] args) throws IOException {
// 创建ArrayList集合
ArrayList<Student> array = new ArrayList<>();
// 创建学生对象
Student s1 = new Student("class01", "林青霞", 30, "西安");
Student s2 = new Student("class02", "张曼玉", 35, "武汉");
Student s3 = new Student("class03", "王祖贤", 33, "南京");
// 把学生对象添加到集合
array.add(s1);
array.add(s2);
array.add(s3);
// 创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt"));
// 遍历集合,得到每一个学生对象
for (Student s:array){
StringBuilder sb = new StringBuilder();
sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());
// 调用字符缓冲输出流对象的方法写数据
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
}
}
package com.study_06;
public class Student {
private String sid;
private String name;
private int age;
private String address;
public Student() {
}
public Student(String sid, String name, int age, String address) {
this.sid = sid;
this.name = name;
this.age = age;
this.address = address;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
20.文件到集合改进版
package com.study_06;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class FileTioArrayListDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("students.txt"));
ArrayList<Student> array = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
String[] strArray = line.split(",");
Student s = new Student();
s.setSid(strArray[0]);
s.setName(strArray[1]);
s.setAge(Integer.parseInt(strArray[2]));
s.setAddress(strArray[3]);
array.add(s);
}
br.close();
for (Student s : array) {
System.out.println(s.getSid()+","+s.getName()+","+s.getAge()+","+s.getAddress());
}
}
}
1.集合到文件数据排序改进版
package com.study_07;
public class Student {
private String name;
private int chinese;
private int math;
private int english;
public Student() {
}
public Student(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum() {
return this.chinese + this.math + this.english;
}
}
package com.study_07;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class TreeSetToFileDemo {
public static void main(String[] args) throws IOException {
// 创建TreeSet集合,通过比较器排序进行排序
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 成绩总分从高到低
int num = s2.getSum() - s1.getSum();
// 次要条件
int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
int num3 = num == 0 ? s1.getMath() - s2.getMath() : num2;
int num4 = num == 0 ? s1.getName().compareTo(s2.getName()) : num3;
return num4;
}
});
// 键盘录入学生数据
for (int i = 0; i < 5; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第" + (i + 1) + "个学生信息:");
System.out.println("姓名:");
String name = sc.nextLine();
System.out.println("语文成绩:");
int chinese = sc.nextInt();
System.out.println("数学成绩:");
int math = sc.nextInt();
System.out.println("英语成绩:");
int english = sc.nextInt();
Student s = new Student();
s.setName(name);
s.setChinese(chinese);
s.setMath(math);
s.setEnglish(english);
// 把学生对象添加到TreeSet集合
ts.add(s);
}
// 创建字符缓冲流输出对象
BufferedWriter bw = new BufferedWriter(new FileWriter("ts.txt"));
// 遍历集合,得到每一个学生对象
for (Student s : ts) {
StringBuilder sb= new StringBuilder();
sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());
// 调用字符缓冲输出流对象的方法写数据
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
// 释放资源
bw.close();
}
}
2.复制单级文件夹
3.复制多级文件夹
4.复制文件异常处理
4.特殊操作流
5.标准输入流
System类中有两个静态的成员变量:
- public static final lnputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
- public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
自己实现键盘录入数据:
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in);
写起来太麻烦,Java就提供了一个类实现键盘录入
- Scannersc=new Scanner(System.in);
package com.study_01;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class SystemInDemo {
public static void main(String[] args) throws IOException {
// InputStream is = System.in;
//
int by;
while ((by = is.read())!=-1) {
System.out.println((char) by);
}
//
// // 如何把字节流转换为字符流
// InputStreamReader isr = new InputStreamReader(is);
// // 使用字符流能不能一次读取一行数据
// // 一次读取一行数据是字符缓冲输入流的特有方法
// BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一个字符串:");
String line = br.readLine();
System.out.println("字符串:"+line);
System.out.println("请输入一个整数:");
int i = Integer.parseInt(br.readLine());
System.out.println("整数:"+i);
// 自己实现键盘录入数据太麻烦了
// 所以有了Scanner
}
}
6.标准输出流
输出语句的本质:是一个标准的输出流
- PrintStreamps=System.out;
- PrintStream类有的方法,System.out者都可以使用
package com.study_01;
import java.io.PrintStream;
public class SystemOutDemo {
public static void main(String[] args) {
PrintStream ps = System.out;
// ps.print("hello");
// ps.print(100);
// ps.println("hello");
// ps.print(1500);
// Sysout.out的本质是一个字节输出流
System.out.println("hello");
System.out.println(100);
}
}
7.字节打印流
打印流分类:
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
package com.study_02;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("ps.txt");
// 写数据
// 字节输出流的方法
// ps.write(97); // a
// 使用特有方法写数据
ps.print(97); //97
ps.println();
ps.print(98);
// 释放资源
ps.close();
}
}
package com.study_02;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
// PrintWriter pw = new PrintWriter("pw.txt");
// pw.write("hello");
// pw.write("\r\n");
// pw.flush();
// pw.write("world");
// pw.write("\r\n");
// pw.flush();
// pw.println("hello");
// pw.flush();
// pw.println("world");
// pw.flush();
// 自动刷新
// PrintWriter pw = new PrintWriter(new FileWriter("pw.txt",true));
PrintWriter pw = new PrintWriter(new FileWriter("pw.txt",false));
pw.println("hello");
pw.println("world");
}
}
打印流的特点:
- 只负责输出数据,不负责读取数据
- 有自己的特有方法
字节打印流
- Printstream(String fileName):使用指定的文件名创建新的打印流
- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
8.字符打印流
字符打印流PrintWriter的构造方法
9.复制java文件(打印流改进版)
package com.study_02;
import java.io.*;
public class CopyjavaDemo {
public static void main(String[] args) throws IOException {
/*
BufferedReader br = new BufferedReader(new FileReader("PrintStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
String line;
while ((line = br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
*/
// 读数据
BufferedReader br = new BufferedReader(new FileReader("PrintStreamDemo.java"));
// 打印流写数据
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
String line;
while ((line = br.readLine()) != null) {
pw.println(line);
}
br.close();
pw.close();
}
}
10.对象序列化流
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:
- 对象序列化流:ObjectOutputStream
- 对象反序列化流:ObjectinputStream
对象序列化流:ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectinputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
构造方法:
- ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
序列化对象的方法:
- void writeObject(Objectobj):将指定的对象写入ObjectOutputStream
注意:
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable接口
Serializable
是一个标记接口,实现该接口,不需要重写任何方法
package com.study_03;
import java.io.Serializable;
// 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;
}
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;
}
}
package com.study_03;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
// 创建对象
Student s = new Student("林青霞",30);
oos.writeObject(s);
oos.close();
}
}
11.对象反序列化流
对象反序列化流:ObjectlnputStream
- ObjectinputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
构造方法:
- ObjectinputStream(InputStreamin):创建从指定的InputStream读取的ObjectinputStream
反序列化对象的方法:
- Object readObject0:从ObjectinputStream读取一个对象
package com.study_03;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName()+","+s.getAge());
ois.close();
}
}
12.serialVersionUID&transient
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,抛出InvalidClassException异常
如果出问题了,如何解决呢?
- 给对象所属的类加一个serialVersionUID private static final long serialVersionUID=42L;
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加
transient
关键字修饰,该关键字标记的成员变量不参与序列化过程
13.Properties作为Map集合的使用
Properties概述:
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
练习:Properties作为Map集合的使用
14.Properties作为集合的特有方法
15.Properties和IO流结合的方法
16.游戏次数
需求:请写程序实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)