IO流学习总结

01.第一章:缓冲流_概述

1).什么是缓冲流:之前使用字节流的两个基本流:FileOutputStreamFileInputStream,以及字符流的两个流:

   FileWriterFileReader,在使用它们时,一次读、写一个字节数组/字符数组的形式非常快。我们用的字节数组/字符数组

   就相当于一个缓存区

2).由于这种方式非常快,所以Java类库中也提供了一种缓冲流”--这些缓冲流内部自带一个缓存区--byte/char数组

   用这些流可以提高我们的读、写效率。

3).这些缓冲流基本上没有增加任何的方法,仍然是使用我们学过的方法,只是它们内部的工作方式不一样。

02.第一章:缓冲流_字节缓冲流【两个】

字节流:

A).输出流:OutputStream

|--FileOutputStream(子类)

|--FilterOutputStream(不学)

|--BufferedOutputStream(字节缓冲流)
B).输入流:InputStream

|--FileInputStream(子类)

|--FilterInputStream(不学)

|--BufferedInputStream(字节缓冲流)

注:这两个缓冲流没有增加任何方法,仍然使用父类的方法,只是内部的工作方式不同。

 

03.第一章:缓冲流_字符缓冲流【两个】

字符流:

A).输出流:Writer

|--OutputStreamWriter(转换流--今天讲)

|--FileWriter(子类--基本流)

|--BufferedWriter(缓冲流)

新增特有方法:newLine():输出一个换行符(\r\n)

B).输入流:Reader

|--InputStreamReader(转换流--今天讲)

|--FileReader(子类--基本流)

|--BufferedReader(缓冲流)

新增特有方法:readLine():读取一行。【不读取换行符】

public class Demo {
    public static void main(String[] args) {
        try (BufferedReader bufIn = new BufferedReader(new FileReader("demo02.txt"));
             BufferedWriter bufOut = new BufferedWriter(new FileWriter("demo02_copy_2.txt"))
        ) {
            //1.一次读写一个字符
            /*int c = 0;
            while ((c = bufIn.read()) != -1) {//从缓存区读
                bufOut.write(c);//写入缓存区
            }*/

            //2.一次读写一个字符数组
            /*char[] chArray = new char[512];
            int len = 0;
            while ((len = bufIn.read(chArray)) != -1) {//从缓存区读
                bufOut.write(chArray,0,len);//写入缓存区
            }*/

            //3.一次读写一行
            String row = null;
            while((row = bufIn.readLine()) != null){//从缓存区读
                bufOut.write(row);//写入缓存区
                bufOut.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

04.第一章:缓冲流_练习_文本排序_案例分析

1).读取出师表_.txt”--按行读--BufferedReader://3.侍中、侍郎郭攸之.....

2).解析读取的行,解析为两部分:第一部分:3,第二部分:内容:侍中、侍郎郭攸之.....

3).for(int i = 1 ; i <= 9 ; i++){

String str = map.get(i);//i作键,取内容

out.write(i + "." + str);//1.xxxx
   }

05.第一章:缓冲流_练习_文本排序_案例实现

public class Demo {
    public static void main(String[] args) {
        try (BufferedReader bufIn = new BufferedReader(new FileReader("出师表_.txt"));
             BufferedWriter bufOut = new BufferedWriter(new FileWriter("出师表_复制.txt"))
        ) {

            //定义一个Map
            Map<Integer, String> map = new HashMap<>();
            //一次读取一行
            String row = null;
            while ((row = bufIn.readLine()) != null) {//row = 3.侍中、侍郎郭攸之.....
                //解析row
                Integer id = Integer.valueOf(row.substring(0, 1));//id = 3
                String str = row.substring(1);//str = ".侍中、侍郎郭攸之.....";
                //存储到Map
                map.put(id, str);
            }
            //写个for循环
            for (int i = 1; i <= 9 ; i++) {
                //i做键,到map中取值
                String str = map.get(i);
                //输出到文件
                bufOut.write(i + str);
                bufOut.newLine();
            }
            System.out.println("复制完毕!");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

-------------------------------------------------------------

06.第二章:转换流_编码引出的问题

1).当磁盘上有一个“GBK”编码的文件时,如果我们用IDEA读取,由于IDEA默认编码方式为:UTF-8

    所以会导致读取到程序中的数据:乱码。

2).FileReaderFileWriter只能根据当前运行时环境(IDEA)的编码方式,不能灵活的更改为其它方式。

3).我们可以使用它们的父类:

1).字符输出流:Writer

   |--OutputStreamWriter(转换流)--可以指定编码表

API:从字符流到字节流的桥梁

     程序中:"你好"--> 编码表 --> 字节 --> 字节流 --> 文件

|--FileWriter(基本流)--只能使用默认编码表

2).字符输入流:

   |--InputStreamReader(转换流)--可以指定编码表

API:从字节流到字符流的桥梁

程序中:"你好"<-- 编码表 <-- 字节 <--字节流 <-- 文件

|--FileReader(基本流)--只能使用默认编码表

4).这两个转换流就可以指定某种编码方式来读、写文件。

07.第二章:转换流_转换输出流OutputStreamWriter的使用

public class Demo {
    public static void main(String[] args) {
        try (OutputStreamWriter osw = new OutputStreamWriter(
                            new FileOutputStream("demo05_GBK.txt"),"GBK")) {
            osw.write("你好");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

08.第二章:转换流_转换输入流InputStreamReader的使用

public class Demo {
    public static void main(String[] args) {
        try (InputStreamReader isr = new InputStreamReader(
                                new FileInputStream("demo05_GBK.txt"),"GBK")) {
            int c = 0;
            while ((c = isr.read()) != -1) {
                System.out.println((char)c);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

乱码的产生:文件中的编码和程序编码不一致;

解决乱码问题:将编码变为一致。

09.第二章:转换流_练习_转换文件编码

1).复制一个GBK编码的文件,复制为UTF-8编码的。

2).示例代码:

public class Demo {
    public static void main(String[] args) {
        //1.GBK读取
        try (InputStreamReader in = new InputStreamReader(
                                new FileInputStream("demo06_GBK.txt"),"GBK");
             //2.UTF-8输出
             OutputStreamWriter out = new OutputStreamWriter(
                                new FileOutputStream("demo06_utf8.txt"),"UTF-8")
            ) {
            int c = 0;
            while ((c = in.read()) != -1) {
                out.write(c);
            }
            System.out.println("转换完毕!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

------------------------------------------------------------

10.第三章:序列化_概述:

1).什么是序列化:将内存中的对象(包括:包名,类名)”连同属性名,值一起存储到一个文件中,这个过程叫:序列化。

2).什么是反序列化:将之前序列化的对象,再次的读取到内存中,并创建对象,为属性赋值,这个过程叫:反序列化。

11.第三章:序列化_序列化流ObjectOutputStream

1).注意:被序列化的类,必须实现:java.io.Serializable接口

2).示例代码:

public class Student implements Serializable {
    String name;
    int age;

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

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

测试类:

public class Demo {
    public static void main(String[] args) {
        Student stu = new Student("成龙", 17);

        //序列化对象
        try (ObjectOutputStream oos = new ObjectOutputStream(

new FileOutputStream("demo08_obj.txt"))) {

            oos.writeObject(stu);

            System.out.println("完毕!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

12.第三章:序列化_反序列化ObjectInputStream

public class Demo {
    public static void main(String[] args) {
        try (ObjectInputStream ois = new ObjectInputStream(

new FileInputStream("demo08_obj.txt"))) {

            Object o = ois.readObject();//1.从文件中读取包名" + "类名";2.到项目中找到那个包下的那个类;3.将这个类创建对象;4.参考类中的属性到文件中找对应的值,找到,就为成员属性赋值;
            Student stu = (Student)o;
            System.out.println(stu);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

13.第三章:序列化_关于版本号

1).任何一个被序列化的类,编译器都会隐式的添加一个变量:

   private static final long serialVersionUID = -6642906621147195767L;

2).序列化

3).修改Student

....

String address;//增加属性

4).编译器会自动的修改这个序列号

      private static final long serialVersionUID = 8842906621147195767L;

5).反序列化:

1).比较两个序列号,发现不一致;抛出异常

----------------------------------------------------------------------------------------

建议:由程序员来维护这个序列号:

public class Student implements Serializable {
     //自定义的序列号
    private static final long serialVersionUID = 1L;

    int stuAge;
    String address;

    public Student(int stuAge, String address) {
        this.stuAge = stuAge;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuAge=" + stuAge +
                ", address='" + address + '\'' +
                '}';
    }
}

14.第三章:序列化_禁止属性被序列化transient关键字

1).如果某个属性不想被序列化,可以将这个成员属性修饰为:transient

public class Student implements Serializable {
     String name;
     transient int age;

}

15.第三章:序列化_练习_序列化集合

1).不要在一个文件中同时序列化多个对象,如果要存储多个对象,可以将这个多个对象存储到一个集合中,

   然后将这个集合序列化到文件中。

ArrayList<Student> list = new ArrayList<>();

   要求

1).ArrayList必须实现Serializable接口;

2).Student必须实现Serializable接口;

3).Student中的引用类型的属性必须实现Serializable接口;

这样才可以成功的序列化一个ArrayList对象。

2).示例代码:

1).Student类:

public class Student implements Serializable{
    private static final long serialVersionUID = 1;
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void setAge(int age) {
        this.age = age;
    }
}

2).序列化测试类:

public class Demo {
    public static void main(String[] args) {
        Student stu1 = new Student("成龙", 17);
        Student stu2 = new Student("洪金宝", 19);
        Student stu3 = new Student("甄子丹", 16);
        ArrayList<Student> list = new ArrayList<>();
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);
        try (ObjectOutputStream out = new ObjectOutputStream(
                                        new FileOutputStream("demo10.txt"))) {
            out.writeObject(list);
            System.out.println("序列化完毕!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3).反序列化测试类:

public class Demo02 {
    public static void main(String[] args) {
        try (ObjectInputStream in = new ObjectInputStream(

new FileInputStream("demo10.txt"))) {
            ArrayList<Student> stuList = (ArrayList<Student>)in.readObject();
            for (Student stu : stuList) {
                System.out.println(stu);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

-------------------------------------------------------------

16.第四章:打印流_概述

1).Java提供了两个打印流:

1).字节打印流:PrintStream

2).字符打印流:PrintWriter

2).特点:

1).只有输出流,没有输入流;

2).可以向文件输出,也可以向控制台输出;

 

17.第四章:打印流_字节打印流PrintStream

public class Demo {
    public static void main(String[] args) {
        PrintStream out = System.out;
        out.println("HelloWorld!");

        //可以更改System.out对象为其它PrintWriter,使其向文件输出
        try (PrintStream ps = new PrintStream("demo11.txt")) {

            //将这个流赋值给System.out
            System.setOut(ps);

            //测试
            System.out.println("呵呵,输出到文件了!");

            //还原
            System.setOut(out);
            System.out.println("呵呵,我又回来了!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

=============================================================

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值