Java IO(三)

转换流

在学习字符流(FileReader、FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStreamWriter,这又是什么意思呢?

OutputStreamWriter类

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节
将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去

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

public class Test {
    public static void main(String[] args) throws IOException {
        writeGBK();
        writeUTF();
    }
    /*
     * 转化流对象 OutoutStreamWriter写文本
     * 文本采用GBK的形式写入
     */
    public static void writeGBK() throws IOException{
        // 创建字节流输出流 绑定数据文件
        FileOutputStream fos = new FileOutputStream("c:\\test.txt");
        // 创建转换流对象  构造方法  绑定字节输出流   默认使用系统GBK编码
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        // 转换流写入数据
        osw.write("你好");
        osw.flush();
        
        osw.close();
    }
    
    /*
     * 转化流对象 OutoutStreamWriter写文本
     * 文本采用UTF-8的形式写入
     */
    public static void writeUTF() throws IOException{
        // 创建字节流输出流 绑定数据文件
        FileOutputStream fos = new FileOutputStream("c:\\test1.txt");
        // 创建转换流对象  构造方法  绑定字节输出流   指定UTF-8的编码
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        // 转换流写入数据
        osw.write("你好");
        osw.flush();
        
        osw.close();
    }
}

InputSteamReader类

查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集

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

public class Test2 {
    public static void main(String[] args) throws IOException {
        readGBK();
        readUTF();
    }
    
    /*
     *  转换流,InputSteamReader读取文本
     *  采用系统默认编码表,读取GBK文件
     */
    public static void readGBK()throws IOException{
        //创建自己输入流,传递文本文件
        FileInputStream fis = new FileInputStream("c:\\test.txt");
        //创建转换流对象,构造方法,包装字节输入流
        InputStreamReader isr = new InputStreamReader(fis);
        char[] ch = new char[1024];
        int len = 0;
        while ((len = isr.read(ch)) != -1){
            System.out.println(new String(ch,0,len));
        }       
        isr.close();
    }
    /*
     *  转换流,InputSteamReader读取文本
     *  采用UTF-8编码表,读取文件
     */
    public static void readUTF()throws IOException{
        //创建自己输入流,传递文本文件
        FileInputStream fis = new FileInputStream("c:\\test1.txt");
        //创建转换流对象,构造方法中,包装字节输入流,同时写编码表名
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        char[] ch = new char[1024];
        int len = 0;
        while ((len = isr.read(ch)) != -1){
            System.out.println(new String(ch, 0, len));
        }
        isr.close();
    }
}

转换流子类父类的区别

OutputStreamWriterInputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。

FileWriterFileReader:作为子类,仅作为操作字符文件的便捷类存在,当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码

InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"))默认字符集

InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK")指定GBK字符集。

FileReader fr = new FileReader("a.txt")

这三句代码的功能是一样的,其中第三句最为便捷

注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?
条件:
1、操作的是文件。2、使用默认编码。
总结:
字节--->字符 : 看不懂的--->看的懂的。 需要读。输入流。 InputStreamReader
字符--->字节 : 看的懂的--->看不懂的。 需要写。输出流。 OutputStreamWriter

缓冲流

在我们学习字节流与字符流的时候,大家都进行过读取文件中数据的操作,读取数据量大的文件时,读取的速度会很慢,很影响我们程序的效率,那么,我想提高速度,怎么办?

Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度
缓冲流,根据流的分类分类字节缓冲流与字符缓冲流

字节缓冲流

字节缓冲流根据流的方向,共有2个

  • 写入数据到流中,字节缓冲输出流 BufferedOutputStream
  • 读取流中的数据,字节缓冲输入流 BufferedInputStream

它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test3 {
    public static void main(String[] args) throws IOException {
        bufferedWrite();
        bufferedRead();
        }
    
    public static void bufferedWrite() throws IOException{
        // 创建字节流
        FileOutputStream fos = new FileOutputStream("c:\\test.txt");
        // 创建字节流输出缓冲流对象  构造方法中传递字节流
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        bos.write(100);               // d
        
        byte[] bytes = "HelloWorld".getBytes(); 
        bos.write(bytes);             // HelloWorld
        
        bos.write(bytes, 5, 5);       // World
        
        bos.close();    
    }

    public static void bufferedRead() throws IOException{   
        // 创建字节流
        FileInputStream fis = new FileInputStream("c:\\test.txt");
        // 创建字节流输出缓冲流对象  构造方法中传递字节流
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = bis.read(bytes)) != -1){
            System.out.print(new String(bytes, 0, len)); 
        }                             // dHelloWorldWorld
        bis.close();    
    }       
}

字符缓冲流

  • 字符缓冲输入流 BufferedReader
  • 字符缓冲输出流 BufferedWriter

完成文本数据的高效的写入与读取的操作

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


public class Test4 {
    public static void main(String[] args) throws IOException {
        bufferedWrite();
        bufferedRead();
    }
    
    /* 字符输出流缓冲区流
     * java.io.BufferedWriter 继承 Writer
     * 写入方法 write () 单个字符,字符数组,字符串
     * BufferedWriter(Writer w)传递任意字符输出流
     */
    public static void bufferedWrite() throws IOException{
        // 创建字符输出流 
        FileWriter fw = new FileWriter("c:\\test.txt");
        // 创建字符流缓冲对象  构造方法中传递字符流
        BufferedWriter bw = new BufferedWriter(fw);
        
        bw.write(100);               // d
        bw.flush();
        
        // newLine() 写换行 方法具有平台无关性
        bw.newLine();
        
        bw.write("你好".toCharArray());
        bw.flush();                  // 你好
        
        bw.close();     
    }
    /*
     * 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
     * public String readLine() 读取一个文本行,包含该行内容的字符串,
     * 不包含任何行终止符,如果已到达流末尾,则返回 null
     */
    public static void bufferedRead() throws IOException{
        // 创建字符输出流 
        FileReader fr = new FileReader("c:\\test.txt");
        // 创建字符流缓冲对象  构造方法中传递字符流
        BufferedReader br = new BufferedReader(fr);
        
        // 调用缓冲流的方法 readLine()读取文本行
        // 循环读取文本 结束条件 readLine()返回null
        String line = null;
        int lineNumber = 0;
        while((line = br.readLine()) != null){
            lineNumber ++;
            System.out.println(lineNumber + " " + line);  // 1 d
        }                                                 // 2 你好       
        br.close();
    }
}

流的操作规律

IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?  
把IO流进行了规律的总结(四个明确):

  • 明确一:要操作的数据是数据源还是数据目的。

    • 源:InputStream Reader
    • 目的:OutputStream Writer
      先根据需求明确要读,还是要写。
  • 明确二:要操作的数据是字节还是文本呢?

    • 源:
      字节: InputStream
      文本:Reader
    • 目的:
      字节:OutputStream
      文本:Writer
      已经明确到了具体的体系上。
  • 明确三:明确数据所在的具体设备。

    • 源设备:
      硬盘:文件 File开头。
      内存:数组,字符串。
      键盘:System.in;
      网络:Socket
    • 目的设备:
      硬盘:文件 File开头。
      内存:数组,字符串。
      屏幕:System.out
      网络:Socket
      完全可以明确具体要使用哪个流对象。
  • 明确四:是否需要额外功能呢?

    • 额外功能:
      转换吗?转换流。InputStreamReader OutputStreamWriter
      高效吗?缓冲区对象。BufferedXXX

你可能感兴趣的:(Java IO(三))