Java基础之字符流

158 阅读4分钟

「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战

一、为什么出现字符流

  • 由于字节流操作中文不是特别的方便,所以Java就提供字符流
  • 字符流=字节流+编码表
  • 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
    • 汉字在存储的时候, 无论选择哪种编码存储,第一个字节都是负数

二、字符流中编码解码问题

  • 字符流抽象基类
    • Reader:字符输入流的抽象类
    • Writer:字符输出流的抽象类
  • 字符流中和编码解码问题相关的两个类
    • InputStreamReader:从字节流到字符流的桥梁 它读取字节,并使用指定的编码将其解码为字符 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
    • OutputStreamWriter:是从字符流到字节流的桥梁 是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
package test;

import java.io.*;

public class Demo {
    public static void main(String[] args) throws IOException {
//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"),"GBK");
        osw.write("中国");
        osw.close();

//1,        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"));
        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"),"GBK");
        int ch;
        while((ch= isr.read()) !=-1) {
            System.out.print((char)ch); //1:�й�;2:中国,因为第二次和编码格式GBK一样
        }
        isr.close();
    }
}

三、字符输出流

方法名说明
void write(int c)写一个字符
void write(char[ ] cbuf)写一个字符数组
void write(char[ ] cbuf,int off,int len)写一个字符数组的一部分
void write(String str)写一个字符串
void write(String str,int off,int len)写一个字符串的一部分
方法名说明
flush()刷新流还可以写数据
close()关闭流,释放资源,但在关闭之前先刷新。关闭后不能写数据
  • 范例
package test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));

        //1,void write(int c) 	写一个字符
        /*osw.write(97);
        osw.write(98);
        //ab
        //void flush():刷新流
        osw.flush();*/

        //2,void write(char[ ] cbuf) 	写一个字符数组
        /*char[] chs = {'a','b','c'};
//        osw.write(chs);
        //abc

        //3,void write(char[ ] cbuf,int off,int len) 	写一个字符数组的一部分
        osw.write(chs,1, 2); //bc,1索引开始,写两个*/

        //4,void write(String str) 	写一个字符串
//        osw.write("abcef"); //abcef

        //5,void write(String str,int off,int len) 	写一个字符串的一部分
        osw.write("abcdef",0, "abcdef".length()); //abcdef
        osw.close();
    }
}

四、字符输入流

方法名说明
int read()一次读一个字符数据
int read(char([ ] cbuf)一次读一个字符数组数据

五、字符缓冲流

  • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途
  • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
  • 构造方法
    • BufferedReader(Reader in)
    • BufferedWriter(Writer out)

六、字符缓冲流特有功能

BufferedReader

  • public String readLine():读一行文字。结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null

BufferedWriter

  • void newLine():写一行行分隔符, 行分隔符字符串由系统属性定义
package test;

import java.io.*;

public class BufferedStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲流输出流
        /*BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\fos.txt"));

        for(int i=0;i<5;i++) {
            bw.write("hello"+i);
//            bw.write("\r\n");
            //2,void newLine():写一行行分隔符, 行分隔符字符串由系统属性定义
            bw.newLine();
            bw.flush();
        }
        bw.close();*/

        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("E:\\test\\fos.txt"));
        //2,public String readLine():读一行文字
        String line;
        while((line=br.readLine()) != null) {
            System.out.println(line);
            /*
            hello0
            hello1
            hello2
            hello3
            hello4*/
        }
        br.close();
    }
}