Java基础学习之字符流(23)

1. 字符流

一个汉字存储:

  • 如果是GBK编码,占用2个字节
  • 如果是UTF-8编码,占用3个字节
package Java23;

import java.io.IOException;
import java.util.Arrays;

public class demo {
    public static void main(String[] args) throws IOException {
//        String s = "abc";
        String s = "中国";//[-28, -72, -83, -27, -101, -67]
//        byte[] bys = s.getBytes();
//        byte[] bys = s.getBytes("UTF-8");//[-28, -72, -83, -27, -101, -67]
        byte[] bys = s.getBytes("GBK");//[-42, -48, -71, -6]
        System.out.println(s);
        System.out.println(Arrays.toString(bys));
    }
}

由于字节流操作中文不是特别方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文

识别中文:

  • 汉字在存储时,无论选择哪种编码存储,第一个字节都是负数

1.1 编码表

按照某种规则,将字符存储到计算机中,称为编码;反之,将存储在计算机中的二进制按照某种规则解析显示出来,称为解码。按照A规则编码,就必须按照A规则解析,防止出现乱码现象。

字符集:

  • 是一个系统支持的所有字符的集合,包括国家文字、标点符号、图形符号、数字等
  • 计算机要准确的存储和识别各种字符集符号就需要字符编码。常见字符编码ASCII字符集、GBXXX字符集、Unicode字符集等。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
编码:

  • byte[] getBytes():使用平台默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
  • byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

解码:

  • String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
  • String(byte[] bytes,String charsetName):通过使用指定的字符集解码指定的字节数组来构造新的String
package Java23;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class demo2 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //定义字符串
        String s = "中国";

        //编码,byte[] getBytes():使用平台默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
        byte[] by = s.getBytes();//[-28, -72, -83, -27, -101, -67]
        System.out.println(Arrays.toString(by));
        //byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
//        byte[] by1 = s.getBytes("UTF-8");//[-28, -72, -83, -27, -101, -67]
        byte[] by1 = s.getBytes("GBK");//[-42, -48, -71, -6]
        System.out.println(Arrays.toString(by1));

        //解码
        //String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
        String ss = new String(by);
        System.out.println(ss);
        //String(byte[] bytes,String charsetName):通过使用指定的字符集解码指定的字节数组来构造新的String
        String sss = new String(by,"GBK");//由于编解码使用的规则不一致,导致乱码
        System.out.println(sss);
    }
}

1.2 字符流中的编码解码问题

字符流抽象基类

  • Reader:字符输入流的抽象类
  • Writer:字符输出流的抽象类

字符流中和编码解码问题相关的两个类:

  • InputStreamReader:字符输入流
  • OutputStreamWriter:字符输出流
package Java23;

import java.io.*;

public class demo1 {
    public static void main(String[] args) throws IOException {
        //OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。
        //OutputStreamWriter(OutputStream out, Charset cs) 创建一个使用给定字符集的OutputStreamWriter。
//        FileOutputStream fos = new FileOutputStream("D:\\lyy\\ja.txt");
//        OutputStreamWriter osw = new OutputStreamWriter(fos);
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\\\lyy\\\\ja.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\\\lyy\\\\ja.txt"),"GBK");

        osw.write("中国");
        osw.write("四月一号");
        osw.close();

        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\\\lyy\\\\ja.txt"),"GBK");
        //一次读取一个字符数据
        int ch;
        while((ch=isr.read())!=-1){
            System.out.print((char) ch);
        }
        isr.close();

    }
}

字符流写数据的五种方式:
在这里插入图片描述

  • flush():刷新流,还可以继续写数据
  • close():关闭流,释放资源,但是在关闭前会先刷新流。一旦关闭就不能继续写数据
package Java23;


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

public class demo3 {
    public static void main(String[] args) throws IOException {
        //字符流写数据的五种方式
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\lyy\\ja2.txt"));

        //写一个字符
        osw.write(97);
        //public void flush()刷新流,使得数据添加入文件
        osw.flush();
        osw.write(98);
        osw.flush();
        osw.write(99);

        //写一个字符数组
        char[] chs = {'a','b','c','d'};
        osw.write(chs);
        //写入字符数组的一部分
        osw.write(chs,0,chs.length);
        osw.write(chs,1,3);

        //写入字符串
        osw.write("asdasj");
        //写入字符串的一部分
        osw.write("sadaiji",0,3);

        //关闭流,先刷新,在关闭资源之前会先刷新数据
        osw.close();

    }
}

字符流写数据的两种方式
在这里插入图片描述

package Java23;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class demo4 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\lyy\\ja2.txt"));

        //一次读一个字符数据
        int ch;
        while((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }

        //一次读一个字符数组
        char[] chs = new char[1024];
        int len;
        while ((len= isr.read(chs))!=-1){
            System.out.print(new String(chs,0,len));
        }

        isr.close();
    }
}

案例复制Java文件

package Java23;

import java.io.*;

public class demo5 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符输入流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\lyy\\src\\java23\\demo.java"));

        //根据目的地创建字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\lyy\\copy.java"));

        //读取并写入
        //一次读写一个字符数据
//        int ch;
//        while ((ch=isr.read())!=-1){
//            osw.write(ch);
//        }
//
        //一次读写一个字符数组
        char[] chs = new char[1024];
        int len;
        while ((len=isr.read(chs))!=-1){
            osw.write(chs,0,len);
        }

        //释放资源
        isr.close();
        osw.close();
    }

}

使用FileWriter和FileReader来替代OutputStreamWriter 和InputStreamReader ,但是如要要对字符流中的编码问题进行操作,需要使用OutputStreamWriter 和InputStreamReader。

  • FileReader:用于读取字符文件的便捷类,FileReader(String fileName)
  • FileWriter:用于写入字符文件的便捷类,FileWriter(String fileName)

案例:复制Java文件

package Java23;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class demo6 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符输入流对象
        FileReader fr = new FileReader("D:\\lyy\\src\\java23\\demo2.java");
        //根据数据源创建字符输出流对象
        FileWriter fw = new FileWriter("D:\\lyy\\copy2.java");

        //读写数据,继承自父类方法也有两种读写数据方式
        //一次读一个字符数据
//        int ch;
//        while ((ch=fr.read())!=-1){
//            fw.write(ch);
            System.out.print((char)ch);
//        }
        //一次读写一个字符数组
        char[] chs = new char[1024];
        int len;
        while ((len=fr.read(chs))!=-1){
            fw.write(chs,0,len);
        }

        //释放资源
        fw.close();
        fr.close();
    }
}

1.3 字符缓冲流

字符缓冲流:

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

构造方法:

  • BufferedWriter(Writer out)
  • BufferedReader(Reader in)
package Java23;

import java.io.*;

public class demo7 {
    public static void main(String[] args)throws IOException {
        //字符缓冲输出流写数据
//        FileWriter fw = new FileWriter("D:\\lyy\\ja.txt");
//        BufferedWriter bw = new BufferedWriter(fw);
        BufferedWriter bw  =new BufferedWriter(new FileWriter("D:\\lyy\\ja.txt"));

        //写入数据
        bw.write("world\n");
        bw.write("hello");

        //字符缓冲输入流读数据
        BufferedReader br = new BufferedReader(new FileReader("D:\\lyy\\ja2.txt"));

        //读取数据
        int len;
        char[] chs  = new char[1024];
        while ((len=br.read(chs))!=-1){
            System.out.print(new String(chs,0,len));
        }

        //释放资源
//        bw.close();
        br.close();
    }
}

案例:Java文件复制,采用字符缓冲流

package Java23;

import java.io.*;

public class demo8 {
    public static void main(String[] args) throws IOException {
        //根据源文件创建字符缓冲流输入对象
        BufferedReader br = new BufferedReader(new FileReader("D:\\lyy\\src\\Java23\\demo7.java"));

        //根据目标文件创建字符缓冲流输出对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\lyy\\copy7.java"));

        //读写字符
        //一次读写一个字符
//        int ch;
//        while ((ch=br.read())!=-1){
//            bw.write(ch);
//        }
        //一次读写一个字符数组
        int len;
        char[] chs = new char[1024];
        while((len=br.read(chs))!=-1){
            bw.write(chs,0,len);
        }
        //释放资源
        br.close();
        bw.close();
    }
}

1.4 字符缓冲流特有功能

BufferWriter:

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

BufferedReader:

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

import java.io.*;

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

        //写数据
        for(int i=0;i<10;i++){
            bw.write("hello"+i);
//            bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();

*/
        //创建字符缓冲流输入对象
        BufferedReader br = new BufferedReader(new FileReader("D:\\\\lyy\\\\ja.txt"));
//        //读一行文字
//        String line = br.readLine();
//        System.out.println(line);
//        //读第二行文字
//        line = br.readLine();
//        System.out.println(line);
        //改用for循环
        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值