Java IO流(三)

1. 字符流

1.1 什么是字符流

        在Java中,字符流是指提供了基于字符的I/O能力的API。

        Java 1.0中提供的基于字节的I/O流API只能支持8位字节流,无法妥善地处理16位Unicode字符。由于需要支持Unicode处理国际化字符,因此Java 1.1 对基础流式I/O库进行了重大的修改,核心是增加了字符流相关的API,处理国际化Unicode字符的编码和解码。

        字符流是以字符(char)为单位读写数据的:一次处理一个 Unicode。字符流的底层仍然是基本的字节流,它封装了字符的编码解码算法。

        字符流以Reader和Writer为核心抽象类,所有的字符输入流类均继承Reader,所有的字符输出流均继承Writer。如下图所示:

        字符流相关子类可以分为节点流和处理流:上图中带阴影的是节点流,不带阴影的是处理流。

1.2 FileWriter示例

        编写代码,使用FileWriter将字符写入文件。代码示意如下:

package api_04;

import java.io.FileWriter;
import java.io.Writer;

public class WriterDemo1 {
    public static void main(String[] args){
        Writer writer = null;
        try{
            writer = new FileWriter("./src/api_04/demo");
            writer.write("Hello World!\n");
            writer.write("Hello FileWriter!\n");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (writer != null){
                try{
                    writer.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

1.3 FileReader示例

  1.         编写代码,使用FileReader从文件中读取字符。代码示意如下:
package api_04;

import java.io.FileReader;
import java.io.Reader;

public class ReaderDemo1 {
    public static void main(String[] args) {
        Reader reader = null;
        try{
            reader = new FileReader("./src/api_04/demo");
            char[] data = new char[5];
            int len = 0;
            while (len !=-1){
                System.out.print(new String(data,0,len));
                len = reader.read(data);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (reader != null){
                try{
                    reader.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

1.4 try-with-resources语法

        在前面的案例中,为了妥善的处理I/O操作中可能出现的异常,并保证在程序结束后关流,我们使用了try-catch-finally语句块。但在实际编码中遇到很多不方便的情况,例如:

  • finally语句块不能访问try语句块中声明的变量
  • finally语句块中需要再次添加try-catch语句块

        幸好Java 7 引入了try-with-resources语法,可以很好地简化上述代码。

        这种称为try-with-resources语法。其要求为:

        1、try后面的括号称为资源说明头,用于创建语句块中使用的资源对象

        2、资源说明头中创建的对象必须实现java.lang.AutoCloseable接口,该接口只有一个方法-close()

        3、资源说明头中可以包含多个创建对象的语句,用分号隔开,最后的分号可以省略

        4、不论如何退出try语句块,都会自动调用所有资源对象的close方法

        5、退出try语句块时,会以与声明资源对象相反的顺序去调用资源对象的close方法

        编写代码,测试try-with-resources的用法。代码示意如下:

package api_04;

import java.io.Closeable;
import java.io.IOException;

public class TWRDemo {
    public static void main(String[] args) {
        try(
            MyStream1 stream1 = new MyStream1();
            MyStream2 stream2 = new MyStream2();
        ){
            System.out.println("try...");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

class MyStream1 implements Closeable{
    @Override
    public void close() throws IOException {
        System.out.println("MyStream1 close...");
    }
}

class MyStream2 implements Closeable{
    @Override
    public void close() throws IOException {
        System.out.println("MyStream2 close...");
    }
}

2. 字符缓冲流

2.1 字符缓冲流概述

        BufferedReader和BufferedWriter分别是字符输入流和字符输出流对应的缓冲流,内置了缓冲区,通过缓冲区来减少实际的物理读写操作,进而提高读写效率。这两个类默认的缓冲区大小均为8192个字符,并支持通过构造器来设置缓冲区大小。

        BufferedReader中还提供了一些增强的I/O操作方法,例如:

  • readLine:读取文本中的一行内容,以'\n','\r'来识别,返回的内容不包含换行符
  • skip:跳过指定数量的字符

        BufferedWriter中没有提供相似的writeLine方法,但是提供了newLine方法,调用时可以向流中输出一个换行符,以达到换行的效果。

2.2 BufferedWriter示例

        编写代码,测试BufferedWriter的用法。代码示意如下:

package api_04;

import java.io.*;

public class BufferedWriterDemo {
    public static void main(String[] args) {
        try(
            Writer writer = new FileWriter("./src/api_04/demo2");
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
        ){
            bufferedWriter.write("Hello world!");
            bufferedWriter.newLine();
            bufferedWriter.write("Hello BufferedWriter!");
            bufferedWriter.newLine();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

2.3 BufferedReader示例

        编写代码,测试BufferedReader的用法。代码示意如下:

package api_04;

import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        try(
            Reader reader = new FileReader("./src/api_04/demo2");
            BufferedReader bufferedReader = new BufferedReader(reader);
        ){
            String line = bufferedReader.readLine();
            while (line!=null) {
                System.out.println(line);
                line = bufferedReader.readLine();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

3. 转换流

3.1 转换流概述

        转换流用于实现字节流和字符流之间的转换。

        InputStreamReader是字节输入流到字符输入流的桥梁,用于将InputStream转换为Reader,可以读取字节数据并根据指定的字符集转换为字符数据。

        OutputStreamWriter是字符输出流到字节输出流的桥梁,用于将OutputStream转换为Writer,可以根据指定的字符集将写出的字符数据转换为字节数据。

3.2 指定字符编码

        InputStreamReader 的构造方法允许设置字符集

  • InputStreamReader(InputStream in,String charsetName):基于给定的字节输入流以及字符编码创建
  • InputStreamReader(InputStream in):该构造方法会根据系统默认字符集创建

        OutputStreamWriter 的构造方法:

  • OutputStreamWriter(OutputStream out,String charsetName):基于给定的字节输出流以及字符编码创建
  • OutputStreamWriter(OutputStream out):该构造方法会根据系统默认字符集创建

3.3 OutputStreamWriter示例

        编写代码,测试OutputStreamWriter的用法,并指定字符编码。代码示意如下:

package api_04;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo {
    public static void main(String[] args) {
        try(
            FileOutputStream fos
                        = new FileOutputStream("./src/api_04/demo3");
            OutputStreamWriter osw
                        = new OutputStreamWriter(fos,"utf-8");
            BufferedWriter bw = new BufferedWriter(osw)
        ){
            bw.write("世界你好!");
            bw.newLine();
            bw.write("转换流你好!");
            bw.newLine();
            System.out.println("写出完毕!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

3.4 InputStreamReader示例

        编写代码,测试InputStreamReader的用法,并指定字符编码。代码示意如下:

package api_04;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class InputStreamReaderDemo {
    public static void main(String[] args) {
        try(
            FileInputStream fis
                        = new FileInputStream("./src/api_04/demo3");
            InputStreamReader isr
                        = new InputStreamReader(fis,"utf-8");
            BufferedReader br = new BufferedReader(isr);
        ){
            String line =br.readLine();
            while(line!=null){
                System.out.println(line);
                line = br.readLine();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangyan_1010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值