笔记(课13)

一阶段:第13天:缓冲流(8.9)

一.转换流

InputStreamReader:字节字符转换输入流,将字节输入流转换为字符输入流
          把外部设备中的二进制数据读取到内存转成字符,指定编码,字节流
OutputStreamWriter:字符转换输出流,将内存中的字符转成字节保存到硬盘中。
          把内存中的字符使用指定的编码占城二进制数据,保存到外部设备
如果使用记事本创建的文件,文件是utf‐8或者unicode编码,文件的前面有一个BOM(Byte Order Mark) 头,BOM用作指定文件使用的编码类型。
GBK编码没有添加bom头。 
utf‐8:EF BB BF unicode 
小端: FF FE 66 00 unicode 
大端 :FE FF 00 66

1.1字节转换输入流(InputStreamReader)

// 使用转换流读取文件
public class Demo5 {
    public static void main(String[] args) throws Exception{
        //创建转换输入流
        FileInputStream fis=new FileInputStream("e:\\cc.txt");
        //InputStreamReader isr=new InputStreamReader(fis,"gbk");//ANSI
        InputStreamReader isr=new InputStreamReader(fis,"utf-8");
        //读取文件
        char[] buf=new char[1024];
        int len=-1;
        while ((len=isr.read(buf))!=-1){
            String str=new String(buf,0,len);
            System.out.println(str);
        }
        //关闭
        isr.close();
    }
}

1.2字节转换输出流(OutputStreamWriter)

// 使用转换流写入内容
public class Demo6 {
    public static void main(String[] args) throws Exception{
        //创建转换输出流
        FileOutputStream fos=new FileOutputStream("e:dd.txt");
        //OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");
        OutputStreamWriter osw=new OutputStreamWriter(fos,"utf-8");
        //写入
        for (int i = 0; i < 10; i++) {
            osw.write("今天晚上不上晚自习,那是不可能的\r\n");
            osw.flush();
        }
        //关闭
        osw.close();
        System.out.println("写入完毕");
    }
}

二.缓冲流

2.1字节流

2.1.1字节输入缓冲流(BufferedInputStream)

//BufferedInputStream,字节输入缓冲流
        FileInputStream fis=new FileInputStream("hello.txt");
        BufferedInputStream bis=new BufferedInputStream(fis);
        //2.读取
        byte[] buf=new byte[1024*4];
        int len=0;
        while ((len=bis.read(buf))!=-1){
            String str=new String(buf,0,len);
            System.out.println(str);
        }
        //关闭
        bis.close();

2.1.2字节输出缓冲流(BufferedOutputStream)

     //BufferedOutputStream 字节输出缓冲流
        //创建缓冲流
        FileOutputStream fos=new FileOutputStream("out.txt");
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //写入
        for (int i = 0; i < 10; i++) {
            //现在还在缓冲区里,没有写入硬盘上
            bos.write("好好学习,天天向上\r\n".getBytes());//可以指定编码
            bos.flush();
        }
        bos.close();
        System.out.println("写入完毕");

2.1.3综合案例1

        // 使用缓冲流实现文件的复制
        //创建缓冲流
        BufferedInputStream bis=new BufferedInputStream(new
        FileInputStream("out.txt"));
        BufferedOutputStream bos=new BufferedOutputStream(new
        FileOutputStream("out2.txt"));
        //读写
        byte[] buf=new byte[1024*4];
        int len=-1;
        while((len=bis.read(buf))!=-1){
            bos.write(buf,0,len);
            bos.flush();
        }
        //关闭
        bos.close();
        bis.close();
        System.out.println("复制完毕");

2.2字符流

 BufferedReader类:
   实例化缓冲字符流的对象 BufferedReader reader = new BufferedReader(new
   FileReader(file));
 BufferedWriter类:
   实例化缓冲字符输出流 BufferedWriter writer = new BufferedWriter(new
   FileWriter(file,true));

2.2.1字符缓冲输入流(BufferedReader)

//BufferedReader 字符缓冲输入流
public class Demo3 {
    public static void main(String[] args) throws Exception{
        //创建对象
        FileReader fr=new FileReader("out.txt");
        BufferedReader br=new BufferedReader(fr);
        //读取
        /*//使用char数组
        char[] buf=new char[1024];
        int len=-1;
        while ((len=br.read(buf))!=-1){
            System.out.println(new String(buf,0,len));
        }*/
        /*//使用readLine()读取一行
        String line=br.readLine();
        System.out.println(line);*/
        //读取多行
        String line=null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        //关闭
        br.close();
    }
}

2.2.2字符缓冲输出流(BufferedWriter)

// BufferedWriter使用字符缓冲输出流
public class Demo4 {
    public static void main(String[] args) throws Exception{
        //创建对象
        FileWriter fw=new FileWriter("buf.txt");
        BufferedWriter bw=new BufferedWriter(fw);
        //写入
        for (int i = 0; i < 10; i++) {
            bw.write("我爱java");
            bw.newLine();//行终止符 windows \r\n  linux \n
            bw.flush();
        }
        //关闭
        bw.close();
    }
}

三.内存流

此时的操作应该以内存为操作点

ByteArrayInputStream: 内存输入流,将内容写入到内存中,是Inputstream的子类
    //定义一个字符串,全部由大写字母组成 。注意不要写中文,否则要进行转换
    String string = "HELLOWORLD"; 
    //向内存中输出内容,注意:跟文件读取不一样,不设置文件路径 
    ByteArrayInputStream bis = new ByteArrayInputStream(string.getBytes()); 
ByteArrayOutputStream:将内存中数据输出,是OutputStream的子类
    //准备从内存中读取内容,注意:跟文件读取不一样,不设置文件路径 
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    //循环结束之后,所有的数据都在ByteArrayOutputStream中
    //取出内容,将缓冲区内容转换为字符串 
    String newString = bos.toString();

3.1字节数组输入流(ByteArrayInputStream)

// ByteArrayInputStream 字节数组输入流
public class Demo5 {
    public static void main(String[] args) throws Exception{
        byte[] data="abcdefg".getBytes();
        //创建字节数组输入流
        ByteArrayInputStream bais=new ByteArrayInputStream(data);
        //读取
        int d=0;
        while ((d=bais.read())!=-1) {
            System.out.print((char)d);
        }
        //关闭(可以不用关)
        bais.close();
    }
}

3.2字节数组输出流(ByteArrayOutputStream)

// ByteArrayOutputStream 字节数组输出流
public class Demo6 {
    public static void main(String[] args) throws Exception{
        //创建字节数组输出流
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        //写入---写内存里了(数组),需要先取出来
        for (int i = 0; i < 10; i++) {
            baos.write("hello".getBytes());
        }
        //关闭
        baos.close();
        //获取数组
        String s=baos.toString();
        System.out.println(s);
    }
}

3.3综合案例2

// 案例:完成字母大小写转换的程序,使用内存流
public class Demo7 {
    public static void main(String[] args) throws Exception{
        String str="HELLO WORLD";
        //创建流
        ByteArrayInputStream bais=new ByteArrayInputStream(str.getBytes());
        //转换流InputStreamReader isr=new InputStreamReader(bais);
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        //转换流OutputStreamWriter osw=new OutputStreamWriter(baos);
        //读取写入
        int d=-1;
        while ((d=bais.read())!=-1){//d=isr....
            //若是中文字符串,这个c会有问题,需要用一下转换流
            char c=Character.toLowerCase((char)d);
            baos.write(c);//转换流osw.weite(c);osw.flush();
        }
        //关闭
        bais.close();
        baos.close();
        //获取数组
        String str2=baos.toString();
        System.out.println(str2);
    }
}

四.标准输入输出流

Java的标准输入/输出分别通过System.in和System.out实现,默认情况下分别代表是键盘和控制台
PrintStream类:PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
PrintWriter类:向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream中的所有 print方法。它不包含用于写入原始字节的方法。

4.1 System.in:BufferedInputStream

 // System.in:BufferedInputStream
public class Demo8 {
    public static void main(String[] args) throws Exception{
     /*System.out.println(System.in.getClass().getName());
     //结果:java.io.BufferedInputStream
        System.out.println(System.out.getClass().getName());
        //结果:java.io.PrintStream*/
        //获取流
        // 运行后等着从控制台输入,回车后就能读出了
        // 程序不会结束,会一直等待从控制台输入,只能强制退出,或者使用判断语句
        // 换行和回车也会被打出来,换行:10,回车:13,回车被隐藏
        InputStream is=System.in;
        /*//读取数据,读取一个
        int d=is.read();
        System.out.println((char)d);*/
        //读取多个
        int d=-1;
        StringBuilder sb=new StringBuilder();
        while ((d=is.read())!=-1){
            if (d==13){
                continue;
            }
            if (d==10){//读取了一行
                System.out.println(sb.toString());
                if (sb.toString().equals("over")){
                    break;//跳出循环
                }
                //清空
                sb.delete(0, sb.length());
            }else {
                sb.append((char)d);
            }
            //System.out.print((char)d);
        }
        //关闭,也可以不用关
        is.close();
    }
}

4.2 System.out:BufferedOutputStream

        // 按行读取,实现控制台输入
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        /*//2.读取
        String line=br.readLine();
        System.out.println(line);*/
        String line=null;
        while (true){
            line=br.readLine();
            System.out.println(line);
            if (line.equals("over")){
                break;
            }
        }
        //关闭
        br.close();

4.3 PrintStream和PrintWriter

4.3.1打印数据

// 使用PrintStream打印数据:字节流; PrintWriter:字符流.本案例结果相同
// 文件---硬盘(外部),java程序---内存(内部)
public class Demo10 {
    public static void main(String[] args) throws Exception{
        //创建打印流
        PrintStream ps=new PrintStream("print.txt");
        PrintWriter pw=new PrintWriter("printw.txt");
        //打印,ps.write(97)输出a
        ps.write(97);ps.println();
        //原样输出
        ps.println(97);ps.println(3.14);ps.println(true);ps.println("我爱java");
        //关闭
        ps.close();
        //打印
        pw.write(97); pw.println();
        //原样输出
        pw.println(97); pw.println(3.14); pw.println(true);pw.println("我爱java");
        //关闭
        pw.close();
    }
}

4.3.2重定向标准输出流

默认是输出到控制台

// 重定向标准输出流
public class Demo11 {
    public static void main(String[] args) throws Exception{
        System.out.println("hello");
        //给System.out重新初始化,使输出到SystemOut.txt中
        PrintStream ps=new PrintStream("SystemOut.txt");
        System.setOut(ps);
        for (int i = 0; i < 10; i++) {
            System.out.println("好久不见");
        }
        ps.close();
    }
}

五.对象流

输出:序列化(内存—>硬盘):将一个对象写入到本地文件中
   ObjectInputStream:对象输出流
输入:反序列化(硬盘—>内存):将一个本地文件中的对象读取出来
   ObjectOutputStream:对象输入流
注意:
序列化对象的类型必须实现Serializable接口。否则不能序列化。
如果向将多个对象序列化到本地,可以借助于集合。
在使用对象流的时候,用于初始化对象流的参数只能是字节流(将对象转换为二进制的形式,然后再把二进制写入文件)

不可以序列化:
	1 transient 修饰的字段:瞬间的
	2 静态的字段
在序列化类中添加字段,保证序列化和反序列化是同一个类,否则,若像序列类中添加字段,反序列化会认为不是同一个序列类,会报异常	
private static final long serialVersionUID = 100L;
// 使用ObjectOutputStream实现序列化
// 使用ObjectIntputStream实现反序列化
public class Demo12 {
    public static void main(String[] args) throws Exception{
        writeObject();
        readObject();
    }
    public static void writeObject() throws Exception{
        //创建流
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("stu.bin"));
        //序列化
        Student shaobo=new Student("少泊",16,"北京");
        Student zhagnsan=new Student("张三",16,"北京");
        Student lisi=new Student("李四",16,"北京");
        ArrayList<Student> list=new ArrayList<>();
        list.add(shaobo);
        list.add(zhagnsan);
        list.add(lisi);
        oos.writeObject(list);
        //oos.writeObject(shaobo);
        //关闭
        oos.close();
        System.out.println("序列化完毕");
    }
    public static void readObject() throws Exception{
        //创建流
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("stu.bin"));
        //读取
       /* Student stu=(Student)ois.readObject();*/
        ArrayList<Student> list=(ArrayList<Student>)ois.readObject();
        for (Student student : list) {
            System.out.println(student.toString());
        }
        /*System.out.println(stu.toString());*/
        //关闭
        ois.close();
        System.out.println("反序列化完毕");
    }
}

六.RandomAccessFile类

支持对随机访问文件的读取和写入
RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。

// 使用RandomAccessFile读写文件
public class Demo1 {
    public static void main(String[] args) throws Exception{
        write();
        read();
    }
    public static void write() throws Exception{
        //创建对象
        RandomAccessFile raf=new RandomAccessFile("ran.txt", "rw");
        //写入
        raf.writeUTF("张三");
        raf.writeInt(20);
        raf.writeDouble(170.5);
        raf.writeBoolean(true);
        raf.writeUTF("李四");
        raf.writeInt(21);
        raf.writeDouble(171.5);
        raf.writeBoolean(false);
        //关闭
        raf.close();
        System.out.println("写入完毕");
    }
    public static void read() throws Exception{
        RandomAccessFile raf=new RandomAccessFile("ran.txt", "rw");
        //设置跳过张三,设置读取指针的偏移量,从0开始,
        //李四:0006+6个字节;21:占4个字节;171.5:占8个字节;false:占1个字节
        //raf.seek(21);
        //跳过21个字节,从当前位置开始跳
        raf.skipBytes(21);
        String name=raf.readUTF();
        int age=raf.readInt();
        Double high=raf.readDouble();
        boolean b=raf.readBoolean();
        System.out.println(name+" "+age+" "+high+" "+b);
        //关闭
        raf.close();
    }
}

七.Properties类

properties可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串
是Map接口的一个实现类,并且是Hashtable的子类
Properties集合中元素也是以键值对的形式存在的

// 使用Properties集合保存数据
public class Demo2 {
    public static void main(String[] args) throws Exception{
        //创建集合
        Properties properties=new Properties();
        //添加
        properties.setProperty("name","少泊");
        properties.setProperty("age", "20");
        properties.setProperty("address", "北京");
        //遍历
        Set<String> keyset=properties.stringPropertyNames();
        for (String key : keyset) {
            System.out.println(key+"----"+properties.getProperty(key));
        }
        //和流有关的方法
        //1.list方法
        System.out.println("----list------");
        properties.list(new PrintStream("prop.properties"));
        System.out.println("输出到控制台:");
        properties.list(System.out);
        //2.load方法:加载
        System.out.println("-----load-------");
        Properties properties1=new Properties();
        properties1.load(new FileReader("prop2.properties"));
        properties1.list(System.out);
        //store方法
        properties.store(new FileWriter("prop3.properties"), "信息");
        //System.getProperties
        Properties sysprop=System.getProperties();
        sysprop.setProperty("myname", "hello");//加入自己的配置
        sysprop.list(System.out);
    }
}

八.装饰者设计模式

扩展类的功能的方法:
(1)继承并重写,缺点:耦合性高
(2)装饰者设计模式
(3)动态代理

  装饰模式指的是在不必改变原类文件和继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
 	 应用场景:需要扩展一个类的功能,或给一个类添加附加职责。

8.1示例1:读取文件

public class RBDemo1 {
    public static void main(String[] args) {
        ReadText readText=new ReadText();
        BufferedReadFile bufferedReadFile=new BufferedReadFile(readText);
        bufferedReadFile.read();
    }
}

// 抽象类:读取文件
public abstract class ReadFile {
    public abstract void read();
}

public class ReadText extends ReadFile{
    @Override
    public void read() {
        System.out.println("读取文本文件");
    }
}

public class BufferedReadFile {//extends ReadFile
    private ReadFile readFile;
    public BufferedReadFile(ReadFile readFile) {
        this.readFile = readFile;
    }
    public void read(){
        System.out.println("带缓冲读取文件");
        readFile.read();
    }
}

8.2示例2:人吃饭

public class Demo1 {
    public static void main(String[] args) {
        Student shaobo=new Student();
        Teacher laowang=new Teacher();
        StrongPerson strongPerson=new StrongPerson(shaobo);
        StrongPerson strongPerson1=new StrongPerson(laowang);
        strongPerson.eat();
        strongPerson1.eat();
    }
}

public abstract class Person {
    public abstract void eat();
}

public class StrongPerson {
    private Person person;
    public StrongPerson(Person person) {
        this.person = person;
    }
    public void eat(){
        System.out.println("喝两口...");
        person.eat();
        System.out.println("抽两口");
        System.out.println("睡一会...");
        System.out.println("玩一会...");
    }
    //添加新的功能
    public void play(){
        System.out.println("xx");
    }
}

public class Student extends Person {
    @Override
    public void eat() {
        System.out.println("学生吃饭");
    }
}

public class Teacher extends Person {
    @Override
    public void eat() {
        System.out.println("老师吃东西");
    }
}

“流”图

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值