字符转换流

编码表

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

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

计算机只能识别二进制数据,早期由来是电信号。
为了方便应用计算机,让它可以识别各个国家的文字。
就将各个国家的文字用数字来表示,并一一对应,形成一张表。

ASCII:美国标准信息交换码。
用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表
           用一个字节的8位表示。

GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
GB18030:GBK的取代版本

BIG-5码 :通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。
Unicode:国际标准码,融合了多种文字。
         所有文字都用两个字节来表示,Java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符。

UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容:
    它将Unicode编码为00000000-0000007F的字符,用单个字节来表示
    它将Unicode编码为00000080-000007FF的字符用两个字节表示 
    它将Unicode编码为00000800-0000FFFF的字符用3字节表示 

编解码

  String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
  byte[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组

  编码:把看得懂的变成看不懂的
  String -- byte[]

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

  举例:谍战片(发电报,接电报)

  码表:小本子
        字符  数值

  要发送一段文字:
        今天晚上在老地方见

        发送端:今 -- 数值 -- 二进制 -- 发出去
        接收端:接收 -- 二进制 -- 十进制 -- 数值 -- 字符 -- 今

        今天晚上在老地方见

  编码问题简单,只要编码解码的格式是一致的。
package cn.itcast_01;

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

public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "你好";

        // String -- byte[]
        byte[] bys = s.getBytes(); // [-60, -29, -70, -61]
        // byte[] bys = s.getBytes("GBK");// [-60, -29, -70, -61]
        // byte[] bys = s.getBytes("UTF-8");// [-28, -67, -96, -27, -91, -67]
        System.out.println(Arrays.toString(bys));

        // byte[] -- String
        String ss = new String(bys); // 你好
        // String ss = new String(bys, "GBK"); // 你好
        // String ss = new String(bys, "UTF-8"); // ???
        System.out.println(ss);
    }
}

转换流

OutputStreamWriter

构造

  OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
  OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
  把字节流转换为字符流。
  字符流 = 字节流 +编码表。
package cn.itcast_02;

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(
        // "osw.txt")); // 默认GBK
        // OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
        // "osw.txt"), "GBK"); // 指定GBK
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
                "osw.txt"), "UTF-8"); // 指定UTF-8
        // 写数据
        osw.write("中国");

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

方法

  OutputStreamWriter的方法:
  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):写一个字符串的一部分

  面试题:close()和flush()的区别?
      A:close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
      B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
package cn.itcast_03;

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(
                "osw2.txt"));

        // 写数据
        // public void write(int c):写一个字符
        // osw.write('a');
        // osw.write(97);
        // 为什么数据没有进去呢?
        // 原因是:字符 = 2字节
        // 文件中数据存储的基本单位是字节。
        // void flush()

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

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

        // public void write(String str):写一个字符串
        // osw.write("我爱林青霞");

        // public void write(String str,int off,int len):写一个字符串的一部分
        osw.write("我爱林青霞", 2, 3);

        // 刷新缓冲区
        osw.flush();
        // osw.write("我爱林青霞", 2, 3);

        // 释放资源
        osw.close();
        // java.io.IOException: Stream closed
        // osw.write("我爱林青霞", 2, 3);
    }
}

InputStreamReader

构造

  InputStreamReader(InputStream is):用默认的编码读取数据
  InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
package cn.itcast_02;

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

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        // InputStreamReader isr = new InputStreamReader(new FileInputStream(
        // "osw.txt"));

        // InputStreamReader isr = new InputStreamReader(new FileInputStream(
        // "osw.txt"), "GBK");

        InputStreamReader isr = new InputStreamReader(new FileInputStream(
                "osw.txt"), "UTF-8");

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

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

方法

  InputStreamReader的方法:
  int read():一次读取一个字符
  int read(char[] chs):一次读取一个字符数组
package cn.itcast_03;

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

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream(
                "StringDemo.java"));

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

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

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

转换流的简化写法

  由于我们常见的操作都是使用本地默认编码,所以,不用指定编码。
  而转换流的名称有点长,所以,Java就提供了其子类供我们使用。

  OutputStreamWriter = FileOutputStream + 编码表(GBK)
  FileWriter = FileOutputStream + 编码表(GBK)

  InputStreamReader = FileInputStream + 编码表(GBK)
  FileReader = FileInputStream + 编码表(GBK)

  需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

  数据源:
        a.txt -- 读取数据 -- 字符转换流 -- InputStreamReader -- FileReader
  目的地:
        b.txt -- 写出数据 -- 字符转换流 -- OutputStreamWriter -- FileWriter
package cn.itcast_04;

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

public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        // 封装数据源
        FileReader fr = new FileReader("a.txt");
        // 封装目的地
        FileWriter fw = new FileWriter("b.txt");

        // 一次一个字符
        // int ch = 0;
        // while ((ch = fr.read()) != -1) {
        // fw.write(ch);
        // }

        // 一次一个字符数组
        char[] chs = new char[1024];
        int len = 0;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
            fw.flush();
        }

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

字符缓冲流

  字符流为了高效读写,也提供了对应的字符缓冲流。
  BufferedWriter:字符缓冲输出流
  BufferedReader:字符缓冲输入流

  BufferedWriter:字符缓冲输出流
  将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 
  可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。

  BufferedReader
  从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 
  可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。 
  BufferedReader(Reader in)
package cn.itcast_05;

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

public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        // BufferedWriter(Writer out)
        // BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
        // new FileOutputStream("bw.txt")));

        BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));

        bw.write("hello");
        bw.write("world");
        bw.write("java");
        bw.flush();

        bw.close();
    }
}

特殊功能(常用)

  字符缓冲流的特殊方法:
  BufferedWriter:
        public void newLine():根据系统来决定换行符
  BufferedReader:
        public String readLine():一次读取一行数据
        包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
package cn.itcast_05;

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

public class BufferedDemo {
    public static void main(String[] args) throws IOException {
        // write();
        read();
    }

    private static void read() throws IOException {
        // 创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("bw2.txt"));

        // public String readLine():一次读取一行数据
        // String line = br.readLine();
        // System.out.println(line);
        // line = br.readLine();
        // System.out.println(line);

        // 最终版代码
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

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

    private static void write() throws IOException {
        // 创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt"));
        for (int x = 0; x < 10; x++) {
            bw.write("hello" + x);
            // bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }

}

练习

  需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

  数据源:
        a.txt -- 读取数据 -- 字符转换流 -- InputStreamReader -- FileReader -- BufferedReader
  目的地:
        b.txt -- 写出数据 -- 字符转换流 -- OutputStreamWriter -- FileWriter -- BufferedWriter
package cn.itcast_06;

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

public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        // 封装数据源
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        // 封装目的地
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

        // 读写数据
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

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

小结

这里写图片描述

添加

LineNumberReader

package cn.itcast_09;

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

/*
 * BufferedReader
 *      |--LineNumberReader
 *          public int getLineNumber()获得当前行号。 
 *          public void setLineNumber(int lineNumber)
 */
public class LineNumberReaderDemo {
    public static void main(String[] args) throws IOException {
        LineNumberReader lnr = new LineNumberReader(new FileReader("my.txt"));

        // 从10开始才比较好
        // lnr.setLineNumber(10);

        // System.out.println(lnr.getLineNumber());
        // System.out.println(lnr.getLineNumber());
        // System.out.println(lnr.getLineNumber());

        String line = null;
        while ((line = lnr.readLine()) != null) {
            System.out.println(lnr.getLineNumber() + ":" + line);
        }

        lnr.close();
    }
}

练习题1

    把ArrayList集合中的字符串数据存储到文本文件

代码

练习题2

从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合

代码

练习题3

复制单极文件夹

代码
练习题4

需求:复制指定目录下的指定文件,并修改后缀名。

代码
练习题5

需求:复制多极文件夹

代码
练习题6

键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低存入文本文件

代码
练习题7

  已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”
  请编写程序读取数据内容,把数据排序后写入ss.txt中。

代码
练习题8

用Reader模拟BufferedReader的readLine()功能

代码
练习题9

自定义类模拟LineNumberReader的特有功能
获取每次读取数据的行号

代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值