欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

缓冲流、转换流、序列化流、Files

程序员文章站 2024-03-06 16:38:20
...

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("程序结束!");
}
图示:

缓冲流、转换流、序列化流、Files

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.第二章:转换流_转换流工作方式图解:

缓冲流、转换流、序列化流、Files

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()