IO流(二. 字符流)

字符流

字符流的底层实际上就是字节流+编码方式

  • 在读写文件需要对文本内容进行处理:按行处理、比较特定字符的时候一般会选择字符流
  • 仅仅读写文件,不处理内容,一般选择字节流

1.1常见字符集(码表)

image-20230407170820017
  • ASCII编码: ASCII字符集(码表)的编码方式,1个字节,最多能表示256个字符,适用于英文

  • GBK编码:GBK字符集(码表)的编码式,用1个字节表示英文,用2个字节表示中文

  • UTF-8编码:Unicode字符集(码表)的编码方式,用1个字节表示英文,用3个字节表示中文

    windows平台默认编码方式是GBK,而ideal和工作中用的编码方式是UTF-8

1.2 编解码方法

编码方法

方法 说明
public byte[] getBytes() 使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
public byte[] getBytes(String charsetName) 使用命名的字符集将这个String编码成一个字节序列,将结果存储到一个新的字节数组中

解码方法

方法 说明
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes, String charsetName) 构造一个新的String由指定用指定的字节的数组解码

示例代码

public class Encoding {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String arr="中国";

        //使用默认的UTF-8编码
        byte[] bytes = arr.getBytes();
        //System.out.println(Arrays.toString(bytes));

        //使用指定的的GBK编码
        //byte[] byte2 = arr.getBytes("GBK");
        //System.out.println(Arrays.toString(byte2));

        //默认使用UTF-8解码
        String s = new String(bytes);
        System.out.println(s);

        //GBK解码
        //String s2 = new String(byte2,"GBK");
        //System.out.println(s2);
    }
}

2.字符输入流

public class FileReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("day11\\a.txt");

        int len;
        char[] c = new char[10];
        while ((len= fr.read(c))!=-1){
            //该String构造方法,可以将传进去的字符类型数组,转换成String输出,并可指定输出部分内容
            System.out.println(c);
            System.out.println(new String(c,0,5));
        }
		//关流
        fr.close();

    }
}

3.字符输出流

public class FileWriteDemo {
    public static void main(String[] args) throws IOException {
        /**
         * 如果文件不存在,则会自动创建
         * 如果存在,则会清空其内容,需需要续写则需要打开构造函数的续写开关
         */
        FileWriter fw = new FileWriter("day11\\a.txt",false);

        fw.write("中国");
        fw.write("\r\n");

        fw.write("97");
        fw.write("\r\n");
        //写入部分String内容,从下标为2的字符开始,往后写入2个,实际写入文件的是 好声
        fw.write("中国好声音",2,2);
        fw.write("\r\n");
        //写入部分数组内容,从下标为3的字符开始,往后写入2个,实际写入文件的是 45
        fw.write(new char[]{'1','2','3','4','5'},3,2);
        fw.write("\r\n");

        /*
        * 字节流会直接与硬盘进行数据交互,所以即便不做close,数据也会被写入文件中
         字符流则会先把数据存入缓冲区当中,再通过flush() 或close() 刷新到本地文件中,如果没有做,文件中就不会有数据
         拓展:在不调用flush() 或close()的情况下,一旦缓冲区超过8192个字节,就会被强制刷新出来
         */
        /*for (int i = 1; i <= 8193; i++) {
            fw.write("q");
        }*/
        //fw.flush();
        fw.close();
    }
}

为什么有时候我们看到文件会乱码?

原因就是编解码方式不一样。另外,字节流读取中文出现乱码的原因是:idea中默认的编码方式是UTF-8,中文占据三个字节,但是字节流读取中文时,一次读一个字节,就会造成乱码。

想要解决乱码问题,就需要用到转换流,将字节流转换成字符流,不存在字符流转字节流,没有必要。

方法名 说明
InputStreamReader(InputStream in) 使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset) 使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out) 使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset) 使用指定的字符编码创建OutputStreamWriter对象

jdk11版本之前,使用以上的转换流

 	//将字节输入流转换成字符输入流
	//如果文件是GBK类型,就在InputStreamReader构造参数里面写上解码方式
       InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\c.txt"),"gbk");
       int a;
       while ((a= isr.read())!=-1){
           System.out.println((char) a);
       }
       isr.close();

jdk11以后,新增了字符流的的构造方法

		//如果文件是GBK,就在FileReader构造参数里面调用Charset.forName("GBK")写上解码方式
        FileReader fr = new FileReader("day11\\c.txt", Charset.forName("gbk"));

        int a;
        while ((a= fr.read())!=-1){
            System.out.println((char) a);
        }
        fr.close();

4.字符缓冲流

和字节流一样,字符流同样也有缓冲流,并且还有自己特有的方法

字符缓冲输入流
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("day11\\a.txt"));

        /**
         * 特有的readLine()方法,使用字符缓冲输入流一次读取一整行的数据
         */
        /*String s = "";
        while((s= br.readLine())!=null){
            System.out.println(s);
        }*/

        int len;
        char[] chars = new char[2];
        while ((len=br.read(chars))!=-1){
            System.out.println(new String(chars,0,len));
        }

        br.close();
    }
}

字符缓冲输出流

public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\a.txt"));
        bw.write("admin");

        //bw.write("\r\n");
        //特有的换行方法:newLine(),防止系统换行符冲突,可以跨平台(win,mac,linux)使用
        bw.newLine();
        bw.write("12345");
        bw.close();
    }
}
posted @ 2023-04-07 17:10  七分酷  阅读(43)  评论(0编辑  收藏  举报