Java 基础 43 转换流

2018-02-04  本文已影响10人  小熊先生很不开心

1.1 转换流出现的原因

1.1.1 字节流读数据可能出现问题

  字节流一次读取一个字节的方式读取带有汉字的文件是有问题的,因为你读取到一个字节后就转为字符在控制台输出了,而汉字是由2个字节组成的,所以这里会出问题。

  文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,得到汉字。

1.1.2 案例代码

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //基本字节流一次读取一个字节
//      FileInputStream fis = new FileInputStream("a.txt");
//      
//      int by;
//      while((by=fis.read())!=-1) {
//          System.out.print((char)by);
//      }
//      
//      fis.close();
        
        //String s = "hello";
        //[104, 101, 108, 108, 111]
        String s = "你好";
        //[-60, -29, -70, -61]
        byte[] bys = s.getBytes();
        System.out.println(Arrays.toString(bys));
    }
}

1.1.3 转换流的组成部分

转换流 = 字节流 + 编码表

这句话怎么理解 ? 往下看, 先说编码表

1.2 编码表概述和常见编码表

1.2.1 什么是编码表?

1.2.2 乱码问题

针对同一个数据, 采用的编码和解码不一致导致

Garbled.png

1.3 String类中的编码和解码问题

1.3.1 方法摘要&编码和解码

1.3.2 案例代码

public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //定义一个字符串
        String s = "你好";
        
        //编码
        //byte[] bys = s.getBytes();//使用平台的默认字符集将此 String 编码为 byte 序列
        //默认编码是GBK
        //[-60, -29, -70, -61]
        //byte[] bys = s.getBytes("GBK"); //指定编码GBK
        //[-60, -29, -70, -61]
        byte[] bys = s.getBytes("UTF-8"); //指定编码UTF-8
        //[-28, -67, -96, -27, -91, -67]
        System.out.println(Arrays.toString(bys));
        
        //解码
        //String ss = new String(bys); //通过使用平台的默认字符集解码指定的 byte 数组
//      String ss = new String(bys,"GBK");//指定编码GBK
        String ss = new String(bys,"UTF-8");//指定编码UTF-8
        System.out.println(ss);
    }
}

1.4 转换流中的编码和解码问题

1.4.1 转换流指的是?

  转换流其实就是一个字符流。

  转换流 = 字节流 + 编码表

1.4.2 转换流的构造方法

1.4.3 案例代码

public class ConversionStreamDemo {
    public static void main(String[] args) throws IOException {
        //public OutputStreamWriter(OutputStream out):默认编码GBK
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
        //public OutputStreamWriter(OutputStream out,String charsetName)
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"),"GBK");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"),"UTF-8");
        //调用写数据的方法
        osw.write("你好");
        //释放资源
        osw.close();
        System.out.println("------------------------");
        
        //public InputStreamReader(InputStream in):默认编码GBK
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));
        //public InputStreamReader(InputStream in,String charsetName)
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"),"GBK");
        InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"),"UTF-8");
        //读数据:一次读取一个字符数据
        int ch;
        while((ch=isr.read())!=-1) {
            System.out.print((char)ch);
        }
        //释放资源
        isr.close();
        
    }
}

1.5 OutputStreamWriter写数据的5种方式

1.5.1 方法摘要

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

1.5.2 案例代码


public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //创建字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));
        
        //public void write(int c):写一个字符
//      osw.write(97);
//      osw.write('a');
        //写完数据后,没有发现数据,为什么呢?
        //1字符=2字节
        //文件中的数据存储的基本单位是字节
        
        //public void write(char[] cbuf):写一个字符数组
//      char[] chs = {'a','b','c','d','e'};
//      osw.write(chs);
        
        //public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
//      char[] chs = {'a','b','c','d','e'};
//      osw.write(chs, 1, 3);
        
        //public void write(String str):写一个字符串
//      osw.write("hello");
        
        //public void write(String str,int off,int len):写一个字符串的一部分
        osw.write("hello", 0, 3);
        
//      //void flush():刷新该流的缓冲
//      osw.flush();
//      
//      //释放资源
        osw.close(); //关闭此流,但要先刷新它
    }
}

1.6 InputStreamReader读数据的2种方式

1.6.1 方法摘要

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

1.6.2 案例代码

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象
//      InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        InputStreamReader isr = new InputStreamReader(new FileInputStream("OutputStreamWriterDemo.java"));
        
        //public int read():一次读取一个字符
//      int ch;
//      while((ch=isr.read())!=-1) {
//          System.out.print((char)ch);
//      }
        
        //public int read(char[] cbuf):一次读取一个字符数组
        char[] chs = new char[1024];
        int len;
        while((len=isr.read(chs))!=-1) {
            System.out.print(new String(chs,0,len));
        }
        
        //释放资源
        isr.close();
    }
}
上一篇 下一篇

猜你喜欢

热点阅读