「Java进阶」I/O操作必备知识点:字节流读写实例讲解
序
欢迎来到全网最完整的Java进阶知识系列教程!!!每天定时更新!!!
本期的课程,我们继续分享I/O文件读写。
IO文件读写,根据数据格式不同,分为字节流读写和字符流读写,我们今天先讲字节流读写。
如果你正在学习Java,不妨收藏这篇文章,或者关注我,定期收获与Java有关的知识和项目信息!
之前八课的内容,可点击下方获取:
老K玩代码:如何优雅的处理异常--Java进阶知识讲义系列(一)
老K玩代码:包装器类装箱与拆箱的艺术——Java进阶知识讲义系列(二)
老K玩代码:一文讲透Java字符串——Java进阶知识讲义系列(三)
老K玩代码:List的用法和实例详解——Java进阶知识讲义系列(四)
老K玩代码:Set的用法和实例详解——Java进阶知识讲义系列(五)
老K玩代码:Map的用法和实例详解——Java进阶知识讲义系列(六)
老K玩代码:常用集合的排序方法——Java进阶知识讲义系列(七)
老K玩代码:I/O流之File类的用法和实例详解——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一个赞哦,你的支持是我持续输出课程内容最大的动力!
结束语
我是专注于开发领域的 @老K玩代码,会持续生产关于如何学习编程语言的优质内容。
如果你想学习Java编程,或者想精进你的Java编程能力,可以关注我。
如果你对开发、编程有任何疑问或者有想了解的内容,而我暂时没有写到的,也欢迎随时来找我聊聊。