【java基础】14-IO流(2)

1.字符流-编码表

  • 什么是字符集
  1. 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
  2. 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
  • 常见的字符集
    • ASCII字符集:
    1. ASCII:是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
    2. 基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
    • GBXXX字符集:
      GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
    • Unicode字符集:
    1. UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
    2. 编码规则:
      128个US-ASCII字符,只需一个字节编码
      拉丁文等字符,需要二个字节编码
      大部分常用字(含中文),使用三个字节编码
      其他极少使用的Unicode辅助字符,使用四字节编码

要点

问题
编码: 字符转成编号
解码:  把编号转成字符
编码表: 字符和编号之间的对应关系表
字符集: 字符的集合,字符集会对应一个编码表
    
常见编码表有哪些?
ASCII : 现代英语,美国
GB2312: 简体中文,7000字符
gbk:2万多字符,兼容GB2312
gb18030: 中文最全的码表,包含少数民族文字
iso-8859-1: 欧洲编码 ,拉丁字母
unicode码表: 万国码,全世界主要国家语言的文字字符.
    utf-8 : 变长 英文一个,其他2,中文3,最多4个字节
    utf-16: 固定长度,2个字节,4个字节
    utf-32: 固定4个字节

2.关于字符流

  1. 字节流以字节为单位操作,读取中文可能有问题,因为中文字符与字节不是一个对应一个的关系(idea默认是utf-8编码,中文占3个字节,英文占一个字节,gbk 编码中文占2个字节,英文占一个)
  2. 下面我们学习字符流,读取数据以字符为单位(中英文字符均可)
  3. 字符流 = 字节流 + 编码表(utf-8)
  4. 支持读取中文

3.字符流-编码和解码的方法

  • 相关方法
方法名说明
byte[] getBytes()使用平台的默认字符集将该 String编码为一系列字节
byte[] getBytes(String charsetName)使用指定的字符集将该 String编码为一系列字节
String(byte[] bytes)使用平台的默认字符集解码指定的字节数组来创建字符串
String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组来创建字符串
  • 代码示例
public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //定义一个字符串
      	 String s = "中国a";

        byte[] bys1 = s.getBytes();        //[-28, -72, -83, -27, -101, -67, 97]
        byte[] bys2 = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67, 97]
        byte[] bys3 = s.getBytes("GBK");   //[-42, -48, -71, -6, 97]

        System.out.println(Arrays.toString(bys1));
        System.out.println(Arrays.toString(bys2));
        System.out.println(Arrays.toString(bys3));

        //String ss = new String(bys);
        //String ss = new String(bys,"UTF-8");
        String ss = new String(bys3,"GBK");
        System.out.println(ss);
    }
}

4.字节流读取中文出现乱码的原因

字节流读取中文出现乱码的原因
字节与中文字符不是一一对应的关系!

5.字符流-读取中文的过程

字符流读取中文的过程
由于字节流操作 中文 不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表 !

6.字符流-写出数据

  • 介绍
    Writer:用于写入字符流的抽象父类
    FileWriter:用于写入字符流的常用子类
  • 构造方法
方法名说明
FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(File file, boolean append)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(String fileName)根据给定的文件名构造一个 FileWriter 对象
FileWriter(String fileName, boolean append)根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象
  • 成员方法
方法名说明
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)写一个字符串的一部分
  • 代码示例
public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("myCharStream\\a.txt");

        //void write(int c):写一个字符
//        fw.write(97);
//        fw.write(98);
//        fw.write(99);

        //void writ(char[] cbuf):写入一个字符数组
        char[] chs = {'a', 'b', 'c', 'd', 'e'};
//        fw.write(chs);

        //void write(char[] cbuf, int off, int len):写入字符数组的一部分
//        fw.write(chs, 0, chs.length);
//        fw.write(chs, 1, 3);

        //void write(String str):写一个字符串
//        fw.write("abcde");

        //void write(String str, int off, int len):写一个字符串的一部分
//        fw.write("abcde", 0, "abcde".length());
        fw.write("abcde", 1, 3);
        
        fw.write(System.lineSeparator());//换行符

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

7.字符流-写出数据的注意事项

字符流写出数据的注意事项

8.字符流-flush和close方法

  1. flush(): 刷新流(发送缓冲区中的内容到目标文件) ,流还可以继续使用!
  2. close(): 1.会先刷新流,再关闭 , 关闭后,流不能再使用!

9.字符流-读取数据

介绍

  • Reader: 用于读取字符流的抽象父类
    FileReader: 用于读取字符流的常用子类
  • 构造方法
方法名说明
FileReader(File file)在给定从中读取数据的 File 的情况下创建一个新 FileReader
FileReader(String fileName)在给定从中读取数据的文件名的情况下创建一个新 FileReader
  • 成员方法
方法名说明
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据
  • 代码示例
public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
   
        FileReader fr = new FileReader("myCharStream\\b.txt");

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

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

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

10.字符缓冲输入流-读取数据

字符缓冲流读取数据

  • 字符缓冲流介绍

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

方法名说明
BufferedWriter(Writer out)创建字符缓冲输出流对象
BufferedReader(Reader in)创建字符缓冲输入流对象
  • 代码示例
public class BufferedStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //BufferedWriter(Writer out)
        BufferedWriter bw = new BufferedWriter(new                                                            FileWriter("myCharStream\\bw.txt"));
        bw.write("hello\r\n");
        bw.write("world\r\n");
        bw.close();

        //BufferedReader(Reader in)
        BufferedReader br = new BufferedReader(new                                                           FileReader("myCharStream\\bw.txt"));

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

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

        br.close();
    }
}

11.缓冲流-特有方法

  • 方法介绍
    BufferedWriter:
方法名说明
void newLine()写一行行分隔符,行分隔符字符串由系统属性定义

BufferedReader:

方法名说明
String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
  • 代码示例
public class BufferedStreamDemo02 {
    public static void main(String[] args) throws IOException {

        //创建字符缓冲输出流
        BufferedWriter bw = new BufferedWriter(new                                                          FileWriter("myCharStream\\bw.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("myCharStream\\bw.txt"));

        String line;
        while ((line=br.readLine())!=null) {
            System.out.println(line);
        }

        br.close();
    }
}

12.IO流-小结

IO流小结

1.流体系
2.流的操作步骤
3.流构造

字节流
    InputStream(抽象类)
    	FileInputStream(String/File)
    	BufferedInputStream(InputStream)    缓冲流= 基础流+缓冲区
    
    int read()
    int read(byte[])
    
    OutputStream(抽象类)
    	FileOutputStream(String/File)
    	BufferedOutputStream(OutputStream)  缓冲流= 基础流+缓冲区
    
    write(int)
    write(byte[])
    write(byte[],index,len)
=============================================================================================== 
字符流 = 字节流 + 编码表
    
    Reader(抽象类)
    	FileReader(String/File,Charset.forName("gbk"))默认编码    	
    	BufferedReader(Reader)
    		 String readLine():一次读取一行
    	InputStreamReader(InputStream) : 转换流,把字节流--->字符流
    
        int read() 读取一个字符
        int read(char[])读取一个字符数组
    
    Writer(抽象类)
    	FileWriter(String/File,Charset.forName("utf-8"))    	
    	BufferedWriter(Writer)
    			void newLine():写入换行符
    	OutputStreamWriter(OutputStream) : 转换流
    
        write(int)
        write(char[])
        write(String)
   
文件复制
    	字节流复制(字节,字节数组)
    	字节缓冲流复制(字节,字节数组)
    	字符缓冲流复制文本文件,一次一行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值