Java IO流之字符流(OutputStreamWriter、InputStreamReader、BufferedWriter、BufferedReader)

Java IO流之字符流(OutputStreamWriter、InputStreamReader、BufferedWriter、BufferedReader)

一、字符流出现的原因

​ 由于字节流操作中文不是特别方便,所以,java就提供了字符流

​ 字符流 = 字节流 + 编码表

二、String类中的编码和解码问题

编码: 就是把字符串转换成字节数组

  • 把一个字符串转换成一个字节数组的方法

    • public byte[] getBytes();使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中
    • public byte[] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中

    解码: 把字节数组转换成字符串

  • 把一个字符数组转换成一个字符串的方法

    • public String(byte[] bytes): 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
    • public String(byte[] bytes, String charsetName) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String
  • 编码:把看得懂的变成看不懂的: String – byte[]

  • 解码:把看不懂的变成看得懂的: byte[] – String

    import java.io.UnsupportedEncodingException;
    import java.util.Arrays;
    
    public class Test2 {
        public static void main(String[] args) throws UnsupportedEncodingException {
            String s = "你好";
            //使用IDEA默认的utf-8编码,一个汉字占三个字节
            byte[] bytes = s.getBytes();
            System.out.println(Arrays.toString(bytes));
    
            //指定为GBK编码,一个汉字占两个字节
            byte[] bytes1 = s.getBytes("GBK");
            System.out.println(Arrays.toString(bytes1));
    
            //使用默认utf-8编码表来解码保存了utf-8的字节数组
            String s1 = new String(bytes);
            System.out.println(s1);
    
            //使用GBK编码表解码保存了GBK的字符数组
            String s2 = new String(bytes1, "GBK");
            System.out.println(s2);
    
            //用utf-8解码保存了GBK编码编码表编码的字符串,会出现乱码
            String s3 = new String(bytes1, "UTF-8");
            System.out.println(s3);
        }
    }
    
    //输出:
    [-28, -67, -96, -27, -91, -67]
    [-60, -29, -70, -61]
    你好
    你好
    ���
    

三、OutputStreamWriter

  • 构造方法

    • OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
    • OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
  • 写入数据

    • public void write(int c) 写一个字符
    • public void write(char[] cbuf) 写一个字符数组
    • public void write(char[] cbuf,int off,int len) 写一个字符数组的 一部分
    • public void write(String str) 写一个字符串
    • public void write(String str,int off,int len) 写一个字符串的一部分
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    
    public class Test3 {
        public static void main(String[] args) throws IOException {
            OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("e:\\test.txt"));
            out.write(97);
            out.write("你好");
            char[] chars = {'你', '好'};
            out.write(chars);
            out.flush();
            out.close();
        }
    }
    
    //输出:a你好你好
    

四、InputStreamReader

  • 构造方法

    • InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
    • InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
  • 读入数据

    • public int read() 一次读取一个字符,如果已到达流的末尾,则返回 -1
    • public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
    import java.io.*;
    
    public class Test4 {
        public static void main(String[] args) throws IOException {
        //e:\\test.txt下保存的为"a你好"
            InputStreamReader in = new InputStreamReader(new FileInputStream("e:\\test.txt"));
            //定义一个容器
            char[] chars = new char[100];
            int len = in.read(chars, 0, 17);//从0开始读,读取17个字符放到容器中
            System.out.println(len);
            System.out.println("------------------");
            System.out.println(new String(chars, 0, len));
            System.out.println(String.valueOf(chars, 0, len));
            in.close();
        }
    }
    
    //输出:
    4
    ------------------
    a你好
    a你好
    
  • 使用字符流复制文本文件

    import java.io.*;
    
    public class Test5 {
        public static void main(String[] args) throws IOException {
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("e:\\test.txt"));
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("e:\\test1.txt"));
            int len = 0;
            char[] chars = new char[1024];
            while ((len=inputStreamReader.read(chars))!=-1){
                outputStreamWriter.write(chars,0,len);
                outputStreamWriter.flush();
            }
            outputStreamWriter.close();
            inputStreamReader.close();
        }
    }
    

五、字符缓冲流(BufferedWriter、BufferedReader)

  • 高效的字符输出流: BufferedWriter
    构造方法: public BufferedWriter(Writer w)
  • 高效的字符输入流: BufferedReader
    构造方法: public BufferedReader(Reader e)
  • 字符缓冲流的特殊功能
    • BufferedWriter: public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
    • BufferedReader: public String readLine():一次读取一行数据 是以换行符为标记的,读到换行符就换行 没读到数据返回null

六、把文本文件中的数据存储到集合中

import java.io.*;
import java.util.ArrayList;

public class Test6 {
    public static void main(String[] args) throws IOException {
//        把文本文件中的数据存储到集合中
        BufferedReader bufferedReader = new BufferedReader(new FileReader("file.txt"));
        int len = 0;
        char[] chars = new char[1024 * 8];
        ArrayList list = new ArrayList<>();
        while (true){
            String s = bufferedReader.readLine();
            if(s!=null){
                list.add(s);
            }else {
                break;
            }
        }
        System.out.println(list);
        bufferedReader.close();
    }
}

七、把集合中的数据存储到文本文件

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Test7 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"));
        ArrayList list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        for (String s : list) {
            bufferedWriter.write(s);
            bufferedWriter.newLine();//写入一个换行符
        }
        bufferedWriter.close();
    }
}

你可能感兴趣的:(Java基础)