18.字符流和编码

字符流 

字符流概述

字符流 : 只能操作计算机中的字符文件
    //文件复制案例 : 不管文件类型,全用字节流!
    //操作字符文件时,字节流会不方便,所以推荐使用字符流
    //字符文件 : 拿windows自带的记事本工具打开

    
字符流的本质 : 底层还是字节流,只不过做了高度封装!    //字符流是包装流,字符流带缓冲区
    字符流 = 字节流 + 编码格式;
    //字符输出流输出内容需要刷新缓冲区    !!

字符流的根节点 : Reader/Writer -> 抽象类
普通字符流 : FileWriter/FileReader -> 不常用,效率低
高效字符流 : BufferedWriter/BufferedReader -> 常用,效率高

FileWriter/FileReader

FileWriter/FileReader : 普通字符流

FileWriter : 文件字符输出流
    构造方法 :

FileWriter(String fileName) //目标文件

FileWriter(File file) 
//带追加写  : FileOutputStream/FileWriter

FileWriter(String fileName, boolean append) 

FileWriter(File file, boolean append)

写的方法 :    

一次写一个字符 : void write(int ch)

一次写一个字符数组 :  void write(char[] chs)

一次写一个字符数组的一部分 : void write(char[] chs,int offset,int length)

一次写一个字符串 : void write(String str) 

一次写一个字符串的一部分 : void write(String str,int offset,int length)     

FileReader : 文件字符输入流
    构造方法 : 

FileReader(String fileName) //源文件

FileReader(File file) //源文件

读的方法 : 

一次读一个字符 : int read()

一次读一个字符数组 : int read(char[] chs)

一次读一个字符数组的一部分 : int read(char[] chs,int offset,int length)
        //没有一次读一个字符串的方法

标准代码

普通字符流一次一个字符复制字符文件:

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

public class 普通字符流一次一个字符复制字符文件 {
    public static void main(String[] args) throws IOException {
        //创建流
        FileWriter fw = new FileWriter("目标文件地址");
        FileReader fr = new FileReader("源文件地址");
        //循环读写
        int ch;//存储每次读到的一个字符

        while((ch = fr.read()) != -1){
            //读一个字符,写一个字符
            fw.write(ch);
            //手动刷新
            fw.flush();
        }

        //关流
        fw.close();
        fr.close();
    }
}

普通字符流一次一个字符数组复制字符文件:

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

public class 普通字符流一次一个字符数组复制字符文件 {
    public static void main(String[] args) throws IOException {
        //创建流
        FileWriter fw = new FileWriter("目标文件地址");
        FileReader fr = new FileReader("源文件地址");

        //循环读写
        char[] chs = new char[1024];
        int len;//统计每次读到的字符个数

        while ((len = fr.read(chs)) != -1){
            //读了多少写多少
            fw.write(chs,0,len);
            //刷新
            fw.flush();
        }

        //关流
        fw.close();
        fr.close();
    }
}

BufferedWriter/BufferedReader

BufferedWriter/BufferedReader : 高效字符输出/字符输入流 (自动刷新的缓冲区)
    
构造方法 :
    BufferedWriter(Writer writer)
    BufferedReader(Reader reader)
        
常规读写方法 :
        写的方法:

一次写一个字符 : void write(int ch)

一次写一个字符数组 :  void write(char[] chs)

一次写一个字符数组的一部分 : void write(char[] chs,int offset,int length)

一次写一个字符串 : void write(String str) 

一次写一个字符串的一部分 : void write(String str,int offset,int length)   

        读的方法 : 

一次读一个字符 : int read()

一次读一个字符数组 : int read(char[] chs)

一次读一个字符数组的一部分 : int read(char[] chs,int offset,int length)
        //没有一次读一个字符串的方法  

标准代码

高效字符流一次一个字符复制字符文件:

import java.io.*;

public class 高效字符流一次一个字符复制字符文件 {
    public static void main(String[] args) throws IOException {
        //创建流
        BufferedWriter bw = new BufferedWriter(
                new FileWriter("目标文件地址"));
        BufferedReader br = new BufferedReader(
                new FileReader("源文件地址"));

        //循环读写
        int ch;//存储每次读到的一个字符

        while((ch = br.read()) != -1){
            //读一个字符,写一个字符
            bw.write(ch);
        }

        //关流
        bw.close();
        br.close();
    }
}

高效字符流一次一个字符数组复制字符文件:

import java.io.*;

public class 高效字符流一次一个字符数组复制字符文件 {
    public static void main(String[] args) throws IOException {
        //创建流
        BufferedWriter bw = new BufferedWriter(new FileWriter("目标文件地址"));
        BufferedReader br = new BufferedReader(new FileReader("源文件地址"));

        //循环读写
        char[] chs = new char[1024];
        int len;//统计每次读到的字符个数

        while ((len = br.read(chs)) != -1){
            //读了多少写多少
            bw.write(chs,0,len);
        }

        //关流
        bw.close();
        br.close();
    }
}

高效字符流一次一行复制字符文件:

import java.io.*;

public class 高效字符流一次一行复制字符文件 {
    public static void main(String[] args) throws IOException {
        //创建流
        BufferedWriter bw = new BufferedWriter(
                new FileWriter("目标文件地址"));
        BufferedReader br = new BufferedReader(
                new FileReader("源文件地址"));

        //循环读写
        String line;//来存储每次读到的一行数据

        while((line = br.readLine()) != null){
            //读一行写一行
            bw.write(line);
            //补上换行符
            bw.newLine();
        }

        //关流
        bw.close();
        br.close();
    }
}

编码格式

编码和解码

码 : 二进制码(010101011100011) -> 硬盘中的字节 ->  文件 (字符文件)

编码 : 编写二进制码 (文字 --> 二进制码)  --> 看得懂的到看不懂的

解码 : 解析二进制码 (二进制码 --> 文字) --> 看不懂的到看得懂的

文件乱码的问题

编码 : 编写二进制码 (文字 -(以何种方式编)-> 二进制码)  --> 看得懂的到看不懂的

解码 : 解析二进制码 (二进制码 -(以何种方式解)-> 文字) --> 看不懂的到看得懂的

以何种方式编/以何种方式解 : 编码格式(编码表) 

乱码产生的根本原因 : 编码和解码的方式不一致    

文件乱码的解决方案 : 修改文件的编码格式和平台的编码格式一致!!!

编码表

编码表 : 字节和文字转换之间的 "密码本" ; //如果编码和解码的"密码本"不一致就会乱码!

字符集 : 一个字符集中有多套编码表;
      最基础的字符集 : ASCII (美国标准信息交换码表) -> 只能解决英文环境下的语言编码问题
        //英文字母,数字 是不会乱码的,所有的编码表的前128位都是ASCII
    
    中文字符集 : GB系列 (国标系列)
        GB2312 : 早期的中文编码表 
        GBK : 现在最常用的中文编码表 
            //GBK 是使用2个字节表示一个中文汉字的
                
    "国际统一组织" : 统一了 万维网上的 编码格式
         设计了一个字符集 :  Unicode 字符集
           UTF-8 编码表 : 互联网数据的统一编码格式;
                //UTF-8 编码表 是使用3个字节表示一个中文汉字
            UTF-16
            UTF-32
                
ANSI : 它不是一种编码表--> 本地字符集 : windows系统会根据时区和系统语言自动的切换ANSI本地字符集所代表的编码格式;  
            ANSI = 当前电脑的默认字符集;

String的编码和解码方法

String的编码 : String -> byte[] -> 二进制码

    成员方法

1. byte[] getBytes() : 把调用方法的字符串对象转换成byte[] //按照平台默认的编码格式

2. byte[] getBytes(String charsetName) : 把调用方法的字符串对象转换成byte[] //按照传入的编码格式

String的解码 :二进制码 -> byte[] -> String

    构造方法

String(byte[] bys) : 按照平台默认的编码格式对字节数组进行解码操作
String(byte[] bys,String charsetName) : 按照指定的编码格式对字节数组进行解码操作
	
String(byte[] bys,int offset,int length) : 按照平台默认的编码格式对字节数组进行解码操作
String(byte[] bys,int offset,int length,String charsetName) : 按照指定的编码格式对字节数组进行解码操作

例:

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

public class Demo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //定义一个字符串
        String str = "我爱你";

        //编码操作
        byte[] bys1 = str.getBytes();
        byte[] bys2 = str.getBytes("GBK");

        System.out.println("Arrays.toString(bys1) = " + Arrays.toString(bys1));
        System.out.println("Arrays.toString(bys2) = " + Arrays.toString(bys2));


        //解码
        String str1 = new String(bys1);
        String str2 = new String(bys2,"gbk");

        System.out.println("str1 = " + str1);
        System.out.println("str2 = " + str2);

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值