java关闭inputstream_Java:浅谈InputStream的close方法

原则:最好在任何时候使用InputStream或者OutputStream的时候,在finally中调用close()方法,显式关闭。

一个典型的示例

InputStream in = null;

try {

in = acquireStream();

...

} finally {

if (in != null) in.close();

}

fianlly中的if (in != null) in.close();也可以用IOUtils.closeQuietly(in);代替,需要Apache Commons-IO。

为什么需要调用

InputStream的作用是用来表示从不同数据源产生输入的类,这些数据源包括:

字节数组

String对象

文件

管道

一个由其他种类的流组成的序列,以便我们可以将他们收集合并到一个流内。

其他数据源,如Internet连接等

通常不使用close会导致内存泄露,垃圾回收机制会回收,但是最好自己显式关闭,这并不是特别关键。

关键是当InputStream的数据源是文件或者Internet连接的时候。

OutputStream的作用是如FileOutStream,当不调用close的时候,不会将缓存刷入文件中。

InputStream的数据源是文件时

一个InputStream会韩勇一个极小的kernel资源,一个低级的file handle。

当打开文件时,将文件读入到InputStream,会对文件加锁。当你不考虑文件加锁。当你需要读取另一个文件的时候,会打开一个新的InputStream,kernel会分配另一个descriptor(文件流),一直累加,而一个进程的文件描述表是优先,到最后文件描述表将用被用完,所以为了以防万一,最好每次使用完之后都加一个close()。

测试代码

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

public class TestInputStream {

public static void main(String[] args) {

// createTestFile();

// testInputStreamWithOutClose();

// testInputStreamWithOneFileWithOutClose();

testInputStreamWithClose();

}

/**

* 创建一万个测试文件

*/

public static void createTestFile() {

try {

for (int i = 0; i < 10000; i++) {

FileOutputStream fos = new FileOutputStream(new File(

"/Users/shenpengyan/Documents/workspace/Test/testInputStream/Test" + i));

fos.write(i);

fos.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* 用不同文件,不使用close,有"Too many open files in system"报错

*/

public static void testInputStreamWithOutClose(){

try {

for (int i = 0; i < 10000; i++) {

FileInputStream fis = new FileInputStream(new File(

"/Users/shenpengyan/Documents/workspace/Test/testInputStream/Test" + i));

System.out.println(fis.toString() + " " + i);

// fis.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* 用同一个文件,不加close,有"Too many open files in system"报错

*/

public static void testInputStreamWithOneFileWithOutClose(){

try {

for (int i = 0; i < 10000; i++) {

FileInputStream fis = new FileInputStream(new File(

"/Users/shenpengyan/Documents/workspace/Test/testInputStream/Test1"));

System.out.println(fis.toString() + " " + i);

// fis.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* 加close,无"Too many open files in system"报错

*/

public static void testInputStreamWithClose(){

try {

for (int i = 0; i < 100000; i++) {

FileInputStream fis = new FileInputStream(new File(

"/Users/shenpengyan/Documents/workspace/Test/testInputStream/Test1"));

System.out.println(fis.toString() + " " + i);

fis.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

当不使用close()方法时,会有报错:Too many open files in system

java.io.FileInputStream@7e349a0e 6079

java.io.FileNotFoundException: /Users/shenpengyan/Documents/workspace/Test/testInputStream/Test1 (Too many open files in system)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.(FileInputStream.java:120)

at TestInputStream.testInputStreamWithOneFileWithOutClose(TestInputStream.java:53)

at TestInputStream.main(TestInputStream.java:9)

InputStream的数据源是Internet连接时

这是我实际遇到的情况,实际业务情况为:我需要调用一个图片存储位置,用key读到的图片存到InputStream里面来进行进一步处理,而我忘记了对它进行close,经过测试,处理300左右的请求之后,就不能继续请求了,这是为什么呢?是因为InputStream没有被垃圾回收掉,还一直占用着连接,而图片服务商有连接数限制,导致之后的请求没有返回,被调用的InputStream类如下:

import java.io.FilterInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.SocketException;

import org.apache.http.client.methods.CloseableHttpResponse;

public class ObjectInputStream extends FilterInputStream {

private CloseableHttpResponse httpResponse;

public ObjectInputStream(InputStream in, CloseableHttpResponse httpResponse) {

super(in);

this.httpResponse = httpResponse;

}

public void close() throws IOException {

this.httpResponse.close();

try {

super.close();

} catch (SocketException e) {

// expected from some implementations because the stream is closed

}

}

}

当没有调用close方法的时候,没有调用httpResponse.close();,连接不会关掉,所以就尴尬了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值