【学习笔记】IO 流 (二)

IO 流 (二)

 

字符编码

  • ISO-8859-1 收录了除ASCII 外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。采用一个字节来表示,最多只能表示256个字符

  • UTF-8 针对Unicode码表的可变长度字符编码,采用一个两个或三个字节来表示

  • GB2312 简体中文 采用一个或两个字节来表示,在1995年之前使用

  • GBK 简体中文,是GB2312的升级版,在1995年后使用

  • BIG5 台湾,繁体中文

写文件和读文件时,一定要采取相同的编码,当编码方式和解码方式不一致时,会出现乱码

 

字符流

在介绍字符流之前,我们先看一个案例

package com.iosteam;
​
import java.io.FileInputStream;
​
public class Demo08 {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("f:\\test\\hello.txt");
        int data = 0;
        while ((data = fis.read()) != -1){
            System.out.print((char) data);
        }
    }
}

我们读取一个txt文件,文件中写的是helloworld

image-20220726172822615

如果我们把helloworld 换成中文 “好好学习”,会出现乱码

image-20220726172932970

 

我们可以看到,这个文件的编码方式是UTF-8

image-20220726173019519

UTF-8 对于中文的编码是一个汉字三个字节,所以 “好好学习” 是12个字节

如果我们用字节流读的话,是一个字节一个字节地读,所以把每个汉字拆成三个字节,然后逐个读取输出,所以才造成了乱码

所以我们要使用字符流来读

 

字符流的父类

字符流的父类(抽象类)

  • Reader: 字符输入流

    • public int read() {}

    • public int read(char[] c) {}

    • public int read(char[] b,int off,int len) {}

  • Wirter: 字符输出流

    • public void write(int n){}

    • public void write(String str){}

    • public void write(char[] c){}

 

文件字符流

  • FileReader :

    • public int read(char[] c) //从流中读取多个字符,将读到的内容存到c 数组,返回实际读到的字符数,如果达到文件的尾部,则返回-1

    • public int read() //从流中读取单个字符,并返回

package com.iosteam;
​
​
import java.io.FileReader;
​
public class Demo08 {
    public static void main(String[] args) throws Exception{
        //创建FileReader
        FileReader fr = new FileReader("f:\\test\\hello.txt");
        //单个读取
//        int data = 0;
//        while((data = fr.read()) != -1){
//            System.out.print((char) data);
//        }
        //多个读取,采用缓冲数组
        char[] buf = new char[1024];
        int count = 0;
        while((count = fr.read(buf)) != -1){
            System.out.println(new String(buf,0,count));
        }
        //关闭
        fr.close();
​
    }
}

image-20220726175911410

  • FileWriter

    • public void write(String str) //一次写多个字符

package com.iosteam;
​
import java.io.FileWriter;
​
public class Demo09 {
    public static void main(String[] args) throws  Exception{
        //创建FileWriter
        FileWriter fw = new FileWriter("f:\\test\\write.txt");
        //读取
        for (int i = 0; i < 10; i++) {
            fw.write("java是最好的语言\r\n");
            fw.flush();
        }
        //关闭
        fw.close();
    }
}

image-20220726180857389

 

  • 用文件字符流复制文件

package com.iosteam.file;
​
import java.io.FileReader;
import java.io.FileWriter;
​
public class Deme10 {
    public static void main(String[] args) throws Exception{
        //创建flieReader
        FileReader fr = new FileReader("f:\\test\\write.txt");
        //创建FileWrite
        FileWriter fw = new FileWriter("f:\\test\\write1.txt");
        //读取文件,并且写入文件
        char[] buf = new char[1024];
        int count = 0;
        while((count = fr.read(buf)) != -1){
            fw.write(buf);
            fw.flush();
        }
        fr.close();
        fw.close();
        System.out.println("复制完成");
    }
}

image-20220726181925934

只能复制文本文件,不能复制图片或二进制文件

原因是图片文件没有字符编码,所以图片中的二进制转成字符就会成为乱码,写回去的也是乱码,所以复制以后的图片就会出错

image-20220726183022795

 

所以以后我们复制文件时,可以使用字节流来复制,字节流可以复制任意文件,因为文件在计算机中都是二进制来存储。

 

字符缓冲流

字符缓冲流是字符流的增强,提高字符流读取和写入的功能

  • 高效读写

  • 支持输入换行符

  • 可一次写一行、读一行

BufferedReader:

方法:

1.构造方法:BufferReader(Reader in) //需要传入字符流

2.readLine() //读取一行文本

package com.iosteam.file;
​
import java.io.BufferedReader;
import java.io.FileReader;
​
public class Demo11 {
    public static void main(String[] args) throws Exception{
        //创建BufferReader
        FileReader fr = new FileReader("F:\\test\\write.txt");
        BufferedReader br = new BufferedReader(fr);   //需要传入字符流
        //读取
        //第一种方式:通过创建缓冲数组
//        char[] buf = new char[1024];
//        int count = 0;
//        while((count = br.read(buf)) != -1){
//            System.out.println(new String(buf,0,count));
//        }
        //第二种方式:一行一行的读取
        String str = null;
        while((str = br.readLine()) != null){
            System.out.println(str);
        }
        //关闭
        br.close();
​
    }
}

 

BufferedWriter:

方法:

1.构造方法:BufferedWriter(Writer out); //需要传入字符流

2.newLine() //写一个分隔符

package com.iosteam.file;
​
import java.io.BufferedWriter;
import java.io.FileWriter;
​
public class Demo12 {
    public static void main(String[] args) throws Exception{
        //创建BufferedWriter
        FileWriter fw = new FileWriter("f:\\test\\buffer.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        //写入
        for (int i = 0; i < 10; i++) {
            bw.write("好好学习,天天向上");
            bw.newLine();   //写入一个换行符  windows:\r\n   Linux:\n
            bw.flush();  //刷新缓冲
        }
        //关闭
        bw.close();
​
    }
}

 

打印流

  • PrintWriter: 继承了Writer类

    • 封装了 print() / println() 方法,支持写入后换行

    • 支持数据原样打印

    • 与PrintStream 中的方法相同,唯一区别的地方是,PrintWriter 不包含用于写入原始字节的方法

    package com.iosteam.file;
    ​
    import java.io.PrintWriter;
    ​
    public class Demo13 {
        public static void main(String[] args) throws Exception{
            //创建PrintWriter
            PrintWriter pw = new PrintWriter("f:\\test\\print.txt");
            //打印
            pw.println(100);
            pw.println('w');
            pw.println(true);
            pw.println(3.14);
            //关闭
            pw.close();
        }
    }

    image-20220727151118294

 

 

转换流

  • 桥转换流:把硬盘上的字节流转成内存中的字符流,反之把字符流转换成字节流

 

  • InputStreamReader : 是字节流通向字符流的桥梁

    • 构造方法:InputStreamReader(InputSream in) //需要传递一个字节流

      InputStreamReader(InputSream in,String charsetName) //指定编码方式

    • String getEncoding() //得到编码方式

package com.iosteam.file;
​
import java.io.FileInputStream;
import java.io.InputStreamReader;
​
public class Demo14 {
    public static void main(String[] args) throws Exception{
        //创建InputStreamReader
        FileInputStream fis = new FileInputStream("f:\\test\\write.txt");
        InputStreamReader isr = new InputStreamReader(fis,"utf-8");  //传入字节流和编码方式
        //读取文件
        int data = 0;
        while((data = isr.read()) != -1){
            System.out.print((char) data);
        }
        //关闭
        isr.close();
​
    }
}

 

在这里要注意:我们传入的编码方式一定要与被读文件的编码方式相同,否则就会乱码

image-20220727153548777

 

  • OutputStreamWriter:字符流通向字节流的桥梁

    • 构造方法:OutputStreamWriter(OutputStream out) //需要传入字节流

      OutputStreamWriter(OutputStream out,String charsetName) //指定编码方式

    • getEncoding() //得到编码方式

    package com.iosteam.file;
    ​
    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;
    ​
    public class Demo15 {
        public static void main(String[] args) throws Exception{
            //创建OutputStreamWriter
            FileOutputStream fos = new FileOutputStream("f:\\test\\info.txt");
            OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
            //写入文件
            for (int i = 0; i < 10; i++) {
                osw.write("怎么了怎么了\r\n");
                osw.flush();
            }
            //关闭
            osw.close();
        }
    }

     

posted @ 2022-07-27 15:58  GrowthRoad  阅读(23)  评论(0编辑  收藏  举报