天天看点

I/O流之字节流的读写——Java进阶知识讲义系列(九)

作者:老K玩代码

欢迎来到全网最完整的Java进阶知识系列教程!!!每天定时更新!!!

本期的课程,我们继续分享I/O文件读写。

IO文件读写,根据数据格式不同,分为字节流读写和字符流读写,我们今天先讲字节流读写。

如果你正在学习Java,不妨收藏这篇文章,或者关注我,定期收获与Java有关的知识和项目信息!

I/O流之字节流的读写——Java进阶知识讲义系列(九)

之前八课的内容,可点击下方获取:

老K玩代码:如何优雅的处理异常--Java进阶知识讲义系列(一)

老K玩代码:包装器类装箱与拆箱的艺术——Java进阶知识讲义系列(二)

老K玩代码:一文讲透Java字符串——Java进阶知识讲义系列(三)

老K玩代码:List的用法和实例详解——Java进阶知识讲义系列(四)

老K玩代码:Set的用法和实例详解——Java进阶知识讲义系列(五)

老K玩代码:Map的用法和实例详解——Java进阶知识讲义系列(六)

老K玩代码:常用集合的排序方法——Java进阶知识讲义系列(七)

老K玩代码:I/O流之File类的用法和实例详解——Java进阶知识讲义系列(八)

I/O流之字节流的读写——Java进阶知识讲义系列(九)

接下来就让我们正式开始分享课程内容吧。

一、InputStream类

1. 概念

IO类可以分成四个大类:

. 输入 输出
字节流(常见场景:图片) InputStream OutputStream
字符流(常见场景:文档) Reader Writer

其中,InputStream类是一个字节流输入的抽象类,常见的子类有:FileInputStream、BufferedInputStream、ObjectInputStream等。

2. 输入字节流-代码实现

输入字节流的代码实现一般分为三步:

  • 对象实例化
  • 读取文件
  • 关闭文件

代码示例(代码初构):

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class IODemo {

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

        // ① 对象实例化
        File f = new File("io.jpg");    // 获取文件
        InputStream fis = new FileInputStream(f);    // 利用FileInputStream对象读取文件

        // ②读取文件
        byte[] b = new byte[1024];    // 用来收容读取结果的字节容器
        int len;    // 用来记录每次读取的数据字节数
        while ((len = fis.read(b)) != -1) {
            System.out.println(len);
        }

        // ③关闭文件
        fis.close();
    }
}           

说明:

  • 这里的FileInputStream是InputStream的子类;
  • (len = fis.read(b)) != -1是一种特别的表达式,分为两步: ①将fis.read(b)的返回值保存到len变量中; ②判断重新复制后的len是否为-1。

可以看到,上例这段代码会有IOException异常,为了便于初学者理解,目前我们不对异常处理,而是向上抛出。但这个方法我们并不推荐,建议使用try...catch...finally...语句将异常捕获,具体如下:

代码示例(完整代码):

import java.io.*;

public class IODemo {

    public static void main(String[] args) {

        // ① 对象实例化
        File f = new File("io.jpg");
        InputStream fis = null;

        // ②读取文件
        try {
            fis = new FileInputStream(f);
            byte[] b = new byte[1024];
            int len;
            while((len = fis.read(b)) != -1) {
                System.out.println(len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {

            // ③关闭文件
            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}           

说明:

  • 在创建FileInputStream实例的时候,可能会抛出FileNotFoundException异常,我们用try...catch...捕获;
  • 在fis.read(b)的时候,可能会抛出IOException异常,我们用try...catch...捕获;
  • 由于上述两个异常可以写在同一个代码块,且FileNotFoundException是IOException的子类,我们可以直接用IOException一次性捕获上述两种异常情况;
  • 不论文件读写是否成功,我们都需要在最后把FileInputStream实例close掉,所以把这段逻辑写在finally代码块中;
  • fis.close也可能存在IOException,通过try..catch...捕获;
  • 为避免fis在finally代码块中出现空指针异常(NullPointerException),我们在try...catch...语句外先对fis变量进行声明。

二、OutputStream类

1. 概念

OutputStream类与InputStream类相对应,是一个字节流输出的抽象类,常见的子类有:FileOutputStream、BufferedOutputStream、ObjectOutputStream等;

2. 输出字节流-代码实现

示例代码(代码初构)

import java.io.*;

public class IODemo {

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

        // ① 对象实例化
        File f1 = new File("io1.jpg");
        File f2 = new File("io2.jpg");

        // ②读写文件
        InputStream fis = new FileInputStream(f1);
        OutputStream fos = new FileOutputStream(f2);
        byte[] b = new byte[1024];
        int len;
        while ((len = fis.read(b)) != -1) {
            System.out.println(len);
            fos.write(b);
        }

        // ③关闭文件
        fos.close();
        fis.close();
    }
}           

说明:

  • 上例实现的是创建io1.jpg图片的副本io2.jpg,同学可以在当前目录下准备一张名为io1.jpg的图片

上例为清晰展示流程和步骤,将异常向上抛出,在实际工作中并不推荐这种写法,实践中建议用try...catch...方法捕获异常。

详见下例:

代码示例(完整代码)

import java.io.*;

public class IODemo {

    public static void main(String[] args) {

        // ① 对象实例化
        File f1 = new File("io1.jpg");
        File f2 = new File("io2.jpg");
        InputStream fis = null;
        OutputStream fos = null;

        // ②读写文件
        try {
            fis = new FileInputStream(f1);
            fos = new FileOutputStream(f2);
            byte[] b = new byte[1024];
            int len;
            while((len = fis.read(b)) != -1) {
                System.out.println(len);
                fos.write(b);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {

            // ③关闭文件
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}           

说明:

  • 这里秉承着“先开后关”的编程逻辑,建议先开始读写的fis最后关闭close。

以上是Java进阶知识系列第九讲,关于字节流读写的全部内容。

内容不多,和老K一起每天积累一点点,轻轻松松掌握Java知识。

正在学习的小伙伴记得给老K一个赞哦,你的支持是我持续输出课程内容最大的动力!

I/O流之字节流的读写——Java进阶知识讲义系列(九)

结束语

我是专注于开发领域的 @老K玩代码,会持续生产关于如何学习编程语言的优质内容。

如果你想学习Java编程,或者想精进你的Java编程能力,可以关注我。

如果你对开发、编程有任何疑问或者有想了解的内容,而我暂时没有写到的,也欢迎随时来找我聊聊。

I/O流之字节流的读写——Java进阶知识讲义系列(九)

继续阅读