InputStreamReader 和 OutputStreamReader流

1. 字符流基础简介

1. 常见的编码格式
  1. ASCII码:由一个字节表示,只支持一些基础字符和数字以及一些键盘上的符号…

  2. UTF8: 万国码,支持所有国家的语言文字。针对Unicode码表的可变长字符编码,一般采用2个左右的字节表示一个字符。

  3. GB2312: 是一种常见的简体中文编码,采用1个或2个字节表示一个字符。

  4. GBK: 简体中文,对GB2312的扩充。

面对字符流不能像字节流一样处理,字节流是固定字节读取的。而字符在不同的编码方式中一个字符所占的字节大小是不同的,所以使用字符流的时候一定要注意编码格式问题防止出现乱码。


2. 字符流的父类(抽象类)

Reader字符输入流类,Writer字符输出流类。
在这里插入图片描述

2. FileReader 和 InputStreamReader

  1. InputStreamReader类是一个Reader的实现类,其中InputStreamReader还派生出FileReader类。但是不建议使用FileReader类,InputStreamReader类派生出FileReader有利也有弊。

  2. 有利的一方面就是FileReader类可以简单化操作直接可以面向一个文件的URL地址进行操作,而InputStreamReader类必须基于一个InputStream的实现类。

  3. 弊端就是FileReader无法指定字符集的编码根据OS采用默认的编码格式。而InputStreamReader类在构造时是可以直接设置字符编码的。

    //直接使用一个桌面文件地址构造
    FileReader fr = new FileReader("C:\\Users\\Splay\\Desktop\\hello.txt");
    
    //这里基于FileInputStream类构造实现
    InputStreamReader isr = new InputStreamReader(
            new FileInputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"UTF8");//指定编码
    
  4. 除此之外FileReader类对于InputStreamReader类的扩充只扩充了自己的三种构造方法,其余所有的方法都来自InputStreamReader类。

  5. InputStreamReader是字节流通向字符流的桥梁,它使用指定的字符编码读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换。

    import java.io.*;
    
    public class Demo01 {
        public static void main(String[] args) {
            try {
                //hello.txt中放入       好好学习,天天向上。
                InputStreamReader isr = new InputStreamReader(
                        new FileInputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"UTF8");
                System.out.println("当前编码格式: " + isr.getEncoding());                          //获取字符编码
    
    
                int value = isr.read();                  //这里读取到返回的值是字符编码值,强转才是字符。
                System.out.println((char)value);
    
                char [] c = new char[1024];
                int len = 0;
                while((len = isr.read(c)) != -1){       //这里读到的len是成功读取到的字符长度。
                    System.out.println(new String(c,0,len));
                }
                isr.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在这里插入图片描述


3. FileWriter 和 OutputStreamWriter类

  1. 它们的关系和上面的关系差不多,同样推荐使用OutputStreamWriter类。

  2. **FileWriter类可以控制是否对一个已存在的文件写入数据时:采用尾部追加的方式写入还是覆盖的方式写入;OutputStreamWriter类没有这个机制,它构造时会自动清理文件里的内容! **

    //传入参数为true    采用append数据追加的形式写入数据       false或者默认是覆盖的形式写入数据。
    FileWriter fw = new FileWriter("C:\\Users\\Splay\\Desktop\\hello.txt",true);
    OutputStreamWriter osw = new OutputStreamWriter(
              new FileOutputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"utf8");
    
  3. append方法和write方法是一样的,底层是append调用write。不要被字面意思迷惑,它不是追加!

    public Writer append(CharSequence csq) throws IOException {
        if (csq == null)
            write("null");
        else
            write(csq.toString());
        return this;
    }
    
  4. 对于输出流来说,需要注意一点Reader类没有的。就是一定要flush刷新流,保证回写的成功。

1. FileWriter追加测试
import java.io.*;

public class Demo01 {
    public static void main(String[] args){

        try{
            FileWriter fw = new FileWriter("C:\\Users\\Splay\\Desktop\\hello.txt",true);
            fw.write("我一定好好学习!");               //append和write方法一样,底层是append调用write。
            fw.flush();                                  //刷新流
            System.out.println("FileWriter流末尾追加成功!");

            InputStreamReader isr = new InputStreamReader(
                    new FileInputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"UTF8");
            char[] c = new char[1024];
            int len = 0;
            while((len=isr.read(c)) != -1){             //读取输出
                System.out.println("成功读取: " + new String(c,0,len));
            }
            fw.close();
            isr.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在这里插入图片描述

2. OutputStreamWriter测试
import java.io.*;

public class Demo02 {
    public static void main(String[] args) {
        try{
            //hello.txt中存放    好好学习,天天向上。我一定好好学习!
            OutputStreamWriter osw = new OutputStreamWriter(
                    new FileOutputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"utf8");
            System.out.println("OutputStreamWriter创建完毕,我们下面看看文件内容是否被清空?");

            InputStreamReader isr = new InputStreamReader(
                    new FileInputStream("C:\\Users\\Splay\\Desktop\\hello.txt"),"UTF8");
            char[] c = new char[1024];
            int len = 0;
            while((len=isr.read(c)) != -1){             //读取输出
                System.out.println("1. 成功读取: " + new String(c,0,len)+"\n\n");
            }
            if(len == -1){
                System.out.println("1. 读取失败!");
            }
            osw.write("hello world!");
            osw.flush();

            len = 0;
            while((len=isr.read(c)) != -1){             //读取输出
                System.out.println("2. 成功读取: " + new String(c,0,len)+"\n\n");
            }
            osw.close();
            isr.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

4. 总结

  1. FileReader 和 InputStreamReader推荐使用InputStreamReader,可以设置字符编码。

  2. FileWriter 和 OutputStreamWriter同样推荐使用OutputStreamWriter,可以设置字符编码。

  3. FileWriter可以设置对文件是采用追加还是覆盖的方式写入数据,OutputStreamWriter不能。

  4. OutputStreamWriter创建时会直接对文件进行格式化,直接清空里面的数据。

  5. FileWriter 和 OutputStreamWriter无论哪个类的append方法都是写入的意思,不是字面追加的意思!不是追加!不是追加!底层实现append方法是调用write方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值