day19Java-IO-In(Out)putStreamReader(Writer)-转换流

博客名称
Java-(中级)

In(Out)putStreamReader(Writer)-转换流

java.io.Writer 继承者 java.io.OutputStreamWriter
java.io.Reader 继承者 java.io.InputStreamReader

**注意:**在字节流和转换流,以及字符流,只有转换流是可以指定字符集的。

把字节流转换为字符流。
字符流 = 基本字节流 +编码表。

有了字节流为什么还要字符流?

		字节流读取中文其实是可以的,但是会出现小问题,

字节流读取中文会出现的问题描述

A:字节流读取文件内容一次读取一个字节,在转换为字符的时候,会出现乱码,不方便在控制台观看,如果是写到文件中则不会出现乱码。
B:字节流读取文件内容一次读取一个字节数组,是可以解决中文问题,但是会出现一点小问题。
			比如创建一个字节数组的大小byte[] bys = new byte[1024];
			因为系统是GBK,一个中文需要两个字节来表示,刚好最后一个中文,数组长度不够了,只读取到一个字节,然后再把字节转为字符串,最后一个中文就会出现乱码,因为只读取到了一中文的一个字节。所以说不方便

代码演示

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
 		//FileOutputStream fos = new FileOutputStream("b.txt");
        //一次读取一个字节
        int by = 0;
        while ((by = fis.read())!=-1){
        	//fos.write(by);
            System.out.print((char)by);//hello,中国!,不方便在控制台观看,写到文件中是没有问题的。
        }
        System.out.println("---------------------------");

        FileInputStream fis2 = new FileInputStream("a.txt");
        //一次读取一个字节数组
        byte[] bys = new byte[1024];
        int len =0;
        while((len= fis2.read(bys))!=-1){
            System.out.println(new String(bys,0,len));
        }
    }
}

结果:

hello,中国!
hello,中国!
In(Out)putStreamReader(Writer)-编码和解码

在这里为什么要说编码和解码,因为在字节流和简化字符流还有转换流,只有转换流的构造方法有编码的功能,所以想记录编码和解码。

编码和解码概述:

编码:把看得懂的变成看不懂的
 	 String -- byte[]
  
解码:把看不懂的变成看得懂的
 	 byte[] -- String
  
举例:谍战片(发电报,接电报)
  
码表:小本子
  		字符	数值
  
要发送一段文字:
  		今天晚上在老地方见
  
  		发送端:今 -- 数值 -- 二进制 -- 发出去
 		接收端:接收 -- 二进制 -- 十进制 -- 数值 -- 字符 -- 今
  
  		今天晚上在老地方见
  
  编码问题简单,只要编码解码的格式是一致的。

String中有关编码和解码的构造方法和成员方法:
String(byte[] bytes,):使用默认字符集解码字节数组
String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
byte[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组
byte[] getBytes():使用默认字符集编码把字符串编码为字节数组

代码演示:

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

        // String -- byte[]
        //编码
        //byte[] getBytes():使用默认编码把字符串编码为字节数组
        //因为我的IDEA设置的编码是UTF-8
        byte[] bytes = s.getBytes();
        System.out.println(Arrays.toString(bytes));//[-28, -67, -96, -27, -91, -67]

        //byte[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组
        //将字符串使用GBK编码为字节数组
        byte[] bytes2 = s.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));//[-60, -29, -70, -61]

        // byte[] -- String
        //解码
        //使用默认编码将字节数组转为字符串
        String s2 = new String(bytes);//通过默认构造看出来,默认编码是UTF-8
        System.out.println(s2);

        //指定编码将字节数组转为字符串
        String s3 = new String(bytes2,"gbk");
        System.out.println(s3);
    }
}

结果:

[-28, -67, -96, -27, -91, -67]
[-60, -29, -70, -61]
你好
你好

常用编码表图解
在这里插入图片描述

In(Out)putStreamReader(Writer)-OutputStreamWriter(输出转换流)-构造方法

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

代码演示

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
        //默认字符集utf-8
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt"));
        osw.write("中国");
        osw.close();//中国

        //OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("c.txt"), "gbk");
        osw2.write("中国");//�й�
        osw2.close();
    }
}
In(Out)putStreamReader(Writer)-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()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。

代码演示:

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //public void write(int c):写一个字符
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
        osw.write('我');
        //刷新缓冲区
        osw.flush();//缓冲区刷新,一般是读取的数据比较多的时候,使用。
        //关闭流
        osw.close();

        //public void write(char[] cbuf):写一个字符数组
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("b.txt"));
        char[] chas = {'我','爱','你','中','国'};
        osw2.write(chas);
        //刷新缓冲区
        osw2.flush();
        //关闭流
        osw2.close();

        //public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
        OutputStreamWriter osw3 = new OutputStreamWriter(new FileOutputStream("c.txt"));
        char[] chas2 = {'我','爱','你','中','国'};
        osw3.write(chas2,1,3);
        //刷新缓冲区
        osw3.flush();
        //关闭流
        osw3.close();

        //public void write(String str):写一个字符串
        OutputStreamWriter osw4 = new OutputStreamWriter(new FileOutputStream("d.txt"));
        osw4.write("我爱你中国");
        //刷新缓冲区
        osw4.flush();
        //关闭流
        osw4.close();

        //public void write(String str,int off,int len):写一个字符串的一部分
        OutputStreamWriter osw5 = new OutputStreamWriter(new FileOutputStream("e.txt"));
        osw5.write("我爱你中国",3,2);
        //刷新缓冲区
        osw5.flush();
        //关闭流
        osw5.close();
    }
}

结果:
a.txt

b.txt

我爱你中国

c.txt

爱你中

d.txt

我爱你中国

e.txt

中国
In(Out)putStreamReader(Writer)-InputStreamReader(输入转换流)-构造方法

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

代码演示

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        //InputStreamReader(InputStream is):用默认的编码读取数据
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
         int by =0;
         //读取数据
         while((by=isr.read())!=-1){
             System.out.print((char)by);
         }

         //InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("a.txt"),"gbk");
        int by2 =0;
        //读取数据
        while((by2=isr2.read())!=-1){
            //因为默认字符集是UTF-8,读取使用GBK,那就要乱码。
            System.out.print((char)by2);
        }

    }
}

结果:

我在上海,你在哪?
鎴戝湪涓婃捣,浣犲湪鍝�?
In(Out)putStreamReader(Writer)-InputStreamReader(输入转换流)-成员方法

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

代码演示:

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {

        //int read():一次读取一个字符
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        int by =0;
        //读数据
        while ((by=isr.read())!=-1){
            System.out.print((char)by);
        }
		//关闭流
		isr.close() 
        
        //int read(char[] chs):一次读取一个字符数组
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("b.txt"));
        //定义一个char数组
        char[] chrs = new char[1024];
        int len =0;
        while((len=isr2.read(chrs))!=-1){
            System.out.println(new String(chrs,0,len));
        }
        //关闭流
		isr2.close()
    }
}

结果:

我在上海,你在哪?
我们都有一个家,名字叫中国。
需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
数据源:
  		a.txt -- 读取数据 -- 字符转换流 -- InputStreamReader
目的地:
  		b.txt -- 写出数据 -- 字符转换流 -- OutputStreamWriter

代码演示

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        //封装数据源
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        //封装目的地
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));
        //一次读取一个字符
        int by =0;
        while ((by=isr.read())!=-1){
            osw.write(by);
        }
        //关闭流
        isr.close();
        osw.close();

        //封装数据源
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("a.txt"));
        //封装目的地
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("c.txt"));
        //一次读取一个字符数组
        char[] chas = new char[1024];
        int len = 0;
        while ((len=isr2.read(chas))!=-1){
            //写数据
            osw2.write(chas,0,len);
            //刷新缓冲区
            osw2.flush();
        }
        //关闭流
        isr2.close();
        osw2.close();
    }
}

结果:
写入的内容b.txt和c.txt结果一样

package com.ginger.demo03;

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

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
        //默认字符集utf-8
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt"));
        osw.write("中国");
        osw.close();//中国

        //OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("c.txt"), "gbk");
        osw2.write("中国");//�й�
        osw2.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值