【Java基础】I/O流 —— Java中的流都需要关闭吗?

【Java基础】I/O流 —— Java中的流都需要关闭吗?

目录

一、为什么要关闭流?二、close方法和flush方法1.使用close方法2.使用flush方法

三、流按指向分类四、不用关闭的流

一、为什么要关闭流?

涉及到对外部资源的读写操作,包括网络、硬盘等等的I/O流,如果在使用完毕之后不关闭,会导致资源泄漏以及可能会引起文件锁定等问题。因此,需要在使用完毕之后关闭流。

关闭流是一种资源释放机制,意味着在使用完毕之后归还系统的内存、CPU或者网络等资源,避免资源长时间占用。常见的关闭流的方法是调用close()方法,该方法会将相关的资源释放,可以有效避免导致资源泄漏的问题。 需要注意的是,关闭流的时机非常重要,过早关闭可能会影响正常操作,而过晚关闭则可能导致资源泄漏。在实际开发的时候,使用完毕之后应该及时关闭流。在Java 7之后引入了try-with-resources语法,可以在语法层面上自动关闭流,用法是:

/* 读取文件 */

File file = new File("opsLiya.json");

try (FileInputStream fileInputStream = new FileInputStream(file)) {

/* 操作 */

}catch (IOException e){

/* 异常处理 */

}

当然也可以使用传统的finally代码块关闭流:

InputStream inputStream = null;

try {

inputStream = new FileInputStream("opsLiya.txt");

/* 操作 */

} catch (IOException e) {

/* 异常处理 */

} finally {

if (inputStream != null) {

try {

inputStream.close();

} catch (IOException e) {

/* 异常处理 */

}

}

}

二、close方法和flush方法

1.使用close方法

当我们使用输入流的时候,如FileInputStream,对流进行关闭时,直接调用close方法即可。 close方法的底层如下:

这个close0方法的底层是一个native方法(本地方法)

此方法进行具体的关闭操作。

2.使用flush方法

当我们使用输出流的时候(即写入数据到文件或者网络中),如BufferedOutputStream,对流进行关闭时,需要先调用flush方法再调用close方法。 我们进入到BufferedOutputStream的flush方法的源码可以看到:

方法注释大概的意思是:刷新此缓冲输出流。这将强制将任何缓冲的输出字节写入底层输出流。 也就是说,在关闭流前调用flush方法,会将缓存中的数据强行刷新到输出目标中,避免数据丢失。

三、流按指向分类

Java中的流在指向上可以分为两大类,分别是用于读写内存的流和用于读写外部资源(文件、网络等)的流。 比如,用于读写内存的流又可以根据操作对象分为两类,如下:

操作对象是byte数组:

ByteArrayInputStreamByteArrayOutputStream 操作对象是字符串:

StringReaderStringWriter

而用于读写外部资源的流,有如下这些:

FileInputStream和 FileOutputStream:用于字节流读写文件;FileReader和FileWriter:用于字符流读写文件;BufferedInputStream和BufferedOutputStream:用于缓存读写字节流提升IO性能;BufferedReader和BufferedWriter:用于缓存读写字符流提升IO性能;DataInputStream和DataOutputStream:可以用于读写整数、浮点数等基本类型的字节流;ObjectInputStream和ObjectOutputStream:用于读写Java对象的字节流;Socket和ServerSocket:用于网络数据传输;HttpURLConnection:用于HTTP请求等。

四、不用关闭的流

对于Java中的ByteArrayInputStream和ByteArrayOutputStream,它们都是在内存中进行读写操作,不需要涉及到底层的外部资源(如文件、网络等等),因此在使用完毕后不一定需要显式地调用close方法去关闭。它们占用的内存将会被JVM自动回收。 我们可以去到ByteArrayInputStream的close方法实现是一个空方法,如下:

当然,我们也可以手动释放它们占用的内存——使用try-with-resources语法:

byte[] data = new byte[]{1, 2, 3, 4, 5};

try (ByteArrayInputStream bis = new ByteArrayInputStream(data);

ByteArrayOutputStream bos = new ByteArrayOutputStream()) {

/* 操作 */

} catch (IOException e) {

/* 异常处理 */

}

注意:虽然它的close方法是空实现,但是我们为了保证代码的可读性和健壮性,仍然应该在使用完毕后及时关闭它们。

相关养生推荐

世界杯人物志丨蒂亚戈·席尔瓦,连续三届世界杯担任...
bet28365365体育在线

世界杯人物志丨蒂亚戈·席尔瓦,连续三届世界杯担任...

📅 07-27 👁️ 9914
负次方怎么算
betvip5365

负次方怎么算

📅 09-04 👁️ 4142
手机淘宝登陆怎么退出?淘宝网页版如何退出登录
bet28365365体育在线

手机淘宝登陆怎么退出?淘宝网页版如何退出登录

📅 07-03 👁️ 189