缓冲流、转换流、序列化流、Files
01.第一章:缓冲流_概述:
1).我们之前操作字节流,字符流读、写文件时,一次操作一个数组的方式比较快,因为一次可以让磁盘读、写更多的内容,而将这些内容可以一次性的装到“数组”中,数组在这个操作中就起到了一个“缓存”的作用。
2).基于这种原因,Java提供了一种IO流,这种IO流它的主要作用就是提供了一个“缓存区”,目的提高程序读、写的效率;这种流就是:高效缓冲流;
3).字节流:
BufferedOutputStresam
BufferedInputStream
字符流:
BufferedWriter
BufferedReader
02.第一章:缓冲流_字节缓冲流:
1).输出流:BufferdOutputStream(输出的方法:三种)
2).输入流:BufferdInputStream(读取的方法:两种)
3).示例代码:
public static void main(String[] args) throws IOException {
/*FileOutputStream out = new FileOutputStream("demo02_1.txt");
out.write(97);//直接到文件
out.close();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("demo02.txt"));
bos.write(97);//先进入"缓存区"
bos.close();*/
//如果文件是8K
FileInputStream in = new FileInputStream("demo02_1.txt");
byte[] byteArray = new byte[1024];
int b = 0;
while((b = in.read(byteArray)) != -1) {//从磁盘读--读8次,8次的IO
System.out.println("读取的字节:" + b);
System.out.println("转换为字符:" + (char) b);
}
in.close();
BufferedInputStream bufIn = new BufferedInputStream(new FileInputStream("demo02.txt"));
byte[] byteArr = new byte[1024];
int n = 0;
while((n = bufIn.read(byteArr)) != -1) {//从缓存区读取的(缓存区会从磁盘一次性读取8K)--从缓存区读8次(但从磁盘只读1次,1次的IO)
System.out.println("读取的字节:" + n);
System.out.println("转换为字符:" + (char) n);
}
bufIn.close();
System.out.println("程序结束!");
}
图示:
03.第一章:缓冲流_字符缓冲流:
1).输出流:BufferdWriter
特有方法:public void newLine():输出一个换行符;
2).输入流:BuffereReader
特有方法:public String readLine():读取一行(不带换行符)
3).示例代码:
public class Demo {
public static void main(String[] args) throws IOException {
//使用字符缓冲流复制文件
//1.源文件的输入流
BufferedReader bufIn = new BufferedReader(new FileReader("demo03_src.txt"));
//2.目标文件的输出流
BufferedWriter bufOut = new BufferedWriter(new FileWriter("demo03_copy.txt"));
//3.一次读写一个字符数组
/*char[] chArray = new char[1024 * 4];
int len = 0;
while((len = bufIn.read(chArray)) != -1){
bufOut.write(chArray, 0, len);
}*/
//4.一次读取一行
String row = null;
while ((row = bufIn.readLine()) != null) {
bufOut.write(row);
bufOut.newLine();//输出一个与平台无关的换行符:Windows:\r\n,Unix:\n Mac : \r
}
bufOut.close();
bufIn.close();
System.out.println("复制完毕!");
}
}
04.第一章:缓冲流练习文本排序_案例分析:
05.第一章:缓冲流练习文本排序_案例实现:
public class Demo {
public static void main(String[] args) throws IOException {
//1.定义一个:高效缓冲字符输入流
BufferedReader bufIn = new BufferedReader(new FileReader("demo04_src.txt"));
//2.定义一个高效缓冲字符输出流
BufferedWriter bufOut = new BufferedWriter(new FileWriter("demo04_dest.txt"));
//3.一次读取一行,并封装到Map中
Map<String,String> map = new HashMap<>();
String row = null;
while ((row = bufIn.readLine()) != null) {
String[] strArray = row.split("\\.");
map.put(strArray[0], strArray[1]);
}
bufIn.close();
//4.向目标文件输出
for (int i = 1; i <= map.size(); i++) {
String s = i + "." + map.get(i + "");
bufOut.write(s);
bufOut.newLine();
}
bufOut.close();
System.out.println("写入完毕!");
}
}
06.第二章:转换流_为什么要有字符流:
1).各国的语言中的字符所占用的字节数不一定,所以Java语言在“字节流”的基础上提供了一种“字符流”。
2).“字符流”的作用:可以根据用户环境的编码表,对字符进行编码和解码使得程序操作字符比较容易。
07.第二章:转换流_字符编码和字符集:
程序中 《编码》 文件中
"a"--> 字符集"UTF-8" ---> 十进制:97 -->二进制 ---> 0110 0001
程序中 《解码》 文件中
"a" <--- 字符集UTF-8 <-- 十进制97 <--- 0110 0001
字符集有很多:
1).ASCII:美国码表,128个字符,每个字符使用1个字节表示;
2).ISO-8859-1:拉丁码表;兼容ASCII码表,但没有中文;
3).早期:GB2312 : 7000多汉字;
现在:GBK : 2万多汉字;每个汉字占用2个字节;
未来:GB18030 : 7万多汉字;每个汉字占用1个,2个,4个字节
4).Unicode :国际码表,包含几千个中文,每个字符占用2个字节,一共65536个字符
5).UTF-8 :国际码表;包含几万个中文,每个中文占用3个字节。
08.第二章:转换流_编码引出的问题:
1).在磁盘上创建文件:
demo05_GBK.txt
2).使用Windows记事本打开,并键入:你好
此时文件使用Windows的字符集:GBK编码,1个汉字--》2个字节;
3).在程序中读取:
public class Demo {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("demo05_GBK.txt"));//使用IDEA的默认编码:UTF-8
String row = in.readLine();
in.close();
System.out.println(row);//乱码
}
}
4).由于“解码”和“编码”使用的字符集不同,所以产生乱码;
5).我们能不能使用指定的字符集解码呢?
可以,但FileReader和BufferedReader不可以,只能使用平台默认字符集;
可以使用FileReader的父类:InputStreamReader
FileWriter的父类:OutputStreamWriter
09.第二章:转换流_转换输出流OutputStreamWriter的使用:
1).构造方法:
OutputStreamWriter(OutputStream out, String charsetName)
2).示例代码:
public class Demo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("demo06_GBK.txt"), "GBK");
osw.write("你好");//GBK编码-->1个中文2个字节
osw.close();
System.out.println("写入完毕!");
}
}
10.第二章:转换流_转换输入流InputStreamReader的使用:
1).构造方法:
InputStreamReader(InputStream in,String charsetName);
2).示例代码:
public class Demo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new
FileInputStream("demo06_GBK.txt"),"GBK");
int c = 0;
while((c = isr.read()) != -1){
System.out.println((char)c);
}
isr.close();
}
}
11.第二章:转换流_转换流工作方式图解:
12.第二章:转换流练习转换文件编码:
public class Demo {
public static void main(String[] args) {
try (
InputStreamReader in = new InputStreamReader(
new FileInputStream("demo08_GBK.txt"),"GBK");
OutputStreamWriter out = new OutputStreamWriter(
new FileOutputStream("demo08_UTF8.txt"),"UTF-8")
) {
//1.GBK读取
int c = 0;
while ((c = in.read()) != -1) {
//2.UTF-8写入
out.write(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("复制完毕!");
}
}
13.第三章:序列化_概述:
1).什么是“序列化”:指可以将“一个对象连同属性值”存到一个文件中,或者通过网络传输的过程。
2).什么是“反序列化”:将之前序列化的对象,再次加载到内存,并创建对象,将引用返回到程序中。
14.第三章:序列化_序列化流ObjectOutputStream类:
private static void write() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("demo09_Object.txt"));
Student stu = new Student("马云");
//序列化到文件
oos.writeObject(stu);
//关闭流
oos.close();
}
**注:被序列化的对象必须实现:java.io.Serializable接口**
15.第三章:序列化_反序列化ObjectInputStream类:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo09_Object.txt "));
Object obj = ois.readObject();//1.读取文件;2.将这个类在内存中创建对象;3.根据文件中的记录为对象复制;4.将内存中的对象引用返回;
Student stu = (Student)obj;
System.out.println(stu.name);
**注意:反序列化接收的类型必须是序列化时的类型,包括“包名”都要相同;**
16.第三章:序列化_关于版本号:
1).当ObjectInputStream反序列化时,先将我们的类的***和之前序列化到文件中的***进行匹配,如果不相同会抛出异常,禁止反序列化;
2).建议:由程序员来维护这个***:
public class Student implements Serializable {
public String name;
public int age;
//建议自己来维护这个***:
private static final long serialVersionUID = 2L;
.....
}
17.第三章:序列化_禁止属性被序列化transient关键字:
public class Student implements Serializable {
public String name;
public transient int age;
....
}
18.第三章:序列化练习序列化集合:
public class Demo {
public static void main(String[] args) throws Exception {
/*List<Student> list = new ArrayList<>();
list.add(new Student("张三", 18, "男"));
list.add(new Student("李四", 11, "女"));
list.add(new Student("王五", 17, "男"));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("demo12_List.txt"));
oos.writeObject(list);
oos.close();
System.out.println("序列化完毕!");*/
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo12_List.txt"));
Object obj = ois.readObject();
List<Student> stuList = (ArrayList<Student>)obj;
for (Student stu : stuList) {
System.out.println(stu);
}
}
}
19.第四章:打印流_概述:
1).java.io.PrintStream:它是System.out属性的类型;
PrintStream p = System.out;
p.println("HelloWorld");
20.第四章:打印流_字节打印流PrintStream类:
public class Demo {
public static void main(String[] args) throws Exception {
//默认PrintStream是向控制台打印:
System.out.println(97);
//更改流向,向文件
PrintStream p = new PrintStream("demo12.txt");
//将System类的out属性的对象换掉,
System.setOut(p);
//向文件写入
System.out.println(97);//write() + newLine()
System.out.println("输出完毕!");
}
}
总结:
01.能够使用字节缓冲流读取数据到程序
BufferedInputStream bufIn = new BufferedInputStream(new FileInputStream(“demo01.txt”));
byte[] byteArray = new byte[1024];
int len = 0;
while((len = bufIn.read(byteArray)) != -1){//从缓存区读取
String s = new String(byteArray,0,len);
System.out.println(s);
}
02.能够使用字节缓冲流写出数据到文件
BufferedOutputStresam bufOut = new BufferedOutputStream(new FileOutputStream(“demo02.txt”));
bufOut.write(“你好”.getBytes());//向缓存区输出;
bufOut.close();
03.能够明确字符缓冲流的作用和基本用法
BufferedReader:特有方法:readLine()
BufferedWriter:特有方法:newLine();
=================================================
04.能够使用缓冲流的特殊功能
使用特殊功能复制文件:
BufferedReader bufIn = new BufferedReader(new FileReader(“demo03.txt”));
BufferedWriter bufOut = new BufferedWriter(new FileWriter(“demo04.txt”));
String row = null;
while((row = bufIn.readLine()) != null){//readLine()不读取换行符
bufOut.write(row);
bufOut.newLine();//输出一个换行符
}
bufOut.close();
bufIn.close();
05.能够阐述编码表的意义
编码表:记录各国语言字符,与十进制的数字对应关系,将数字转换二进制,在计算机中存储这个二进制就代表这个字符。
06.能够使用转换流读取指定编码的文本文件
InputStreamReader isr = new InputStreamReader(new FileInputStream(“demo01.txt”),”GBK”);
int c = isr.read();//按GBK码表读取
isr.close();
07.能够使用转换流写入指定编码的文本文件
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“demo01.txt”),”GBK”);
out.write(“你好”);//使用GBK编码
out.close();
08.能够说出打印流的特点
1).只有输出流,没有输入流;
2).可以操作文件,也可以操作控制台;
09.能够使用序列化流写出对象到文件
class Student implements Serializable{
}
main(){
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(“demo09.txt”));
Student stu = new Student(“张三”,20);
out.writeObject(stu);
out.close();
}
10.能够使用反序列化流读取文件到程序中
main(){
ObjectInputStream in = new ObjectInputStream(new FileInputStream(“demo09.txt”));
Object obj = in.readObject();
Student stu = (Student)obj;
….
}
A)字节流:(红色:昨天学的)
1).输出流:OutputStream(三种输出的方法)
|–FileOutputStream(基本流)
|–FilterOutputStream(不学)
|–BufferedOutputStream(缓冲流-构造需要基本字节流)
|–PrintStream(System.out)
|–ObjectOutputStream(序列化流)
2).输入流:InputStream(两种读取)
|--FileInputStream(基本流)
|--FilterInputStream(不学)
|--BufferedInputStream(缓冲流--构造需要基本字节流)
|--ObjectInputStream(反序列化流)
B)字符流:
1).输出流:Writer(五种输出的方法)
|–OutputStreamWriter(转换流-构造需要基本字节流)
|–FileWriter(基本流)
|–BufferedWriter(缓冲流-构造需要基本字符流):newLine()
2).输入流:Reader(两种读取)
|–InputStreamReader(转换流–构造需要基本字节流)
|–FileReader(基本流)
|–BufferedReader(缓冲流-构造需要基本字符流):readLine()
上一篇: Redux原理
下一篇: Java I/O缓冲输入流
推荐阅读
-
缓冲流、转换流、序列化流、Files
-
(三)IO流——缓冲字节流、缓冲字符流、转换流
-
字节缓冲流、转换流、字符流
-
java基础之--缓冲流-字节流+字符流+转换流+序列化+打印流
-
JavaIO流_中(IO原理、流的分类(节点流、缓冲流、转换流、输入输出流、对象流、打印流))
-
IO流【字节流、字符流、缓冲流、转换流、序列化流】
-
JAVA基础之转换流和缓冲流
-
JAVA-----IO篇四(缓冲流BufferedWriter以及BufferedReader、转换流outputStreamWriter以及inputStreamWriter)
-
IO--转换流,打印流,序列化的实例详解
-
JAVA基础之转换流和缓冲流