原则:最好在任何时候使用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.<init>(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();,连接不会关掉,所以就尴尬了。

理论依据参考:http://stackoverflow.com/questions/26541513/why-is-it-good-to-close-an-inputstream

Java:浅谈InputStream的close方法的更多相关文章

  1. 浅谈 js 字符串 trim 方法之正则篇

    原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格   等 ...

  2. 浅谈 js 字符串 search 方法

    原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...

  3. 浅谈 js 对象 toJSON 方法

    前些天在<浅谈 JSON.stringify 方法>说了他的正确使用姿势,今天来说下 toJSON 方法吧.其实我觉得这货跟 toString 一个道理,他是给 stringify 方法字 ...

  4. JAVA IO流 InputStream流 Read方法

    read()首先我们来看这个没有参数的read方法,从(来源)输入流中(读取的内容)读取数据的下一个字节到(去处)java程序内部中,返回值为0到255的int类型的值,返回值为字符的ACSII值(如 ...

  5. [iOS、Unity、Android] 浅谈闭包的使用方法

    前言 我们经常所编程语言的的进步速度是落后于硬件的发展速度的. 但是最近几年,闭包语法在各个语言中都有自己的体现形式,例如 • C语言中使用函数指针作为回调函数的入口: • Java和C#语言中的La ...

  6. java 浅谈web系统当中的cookie和session会话机制

    一 Cookie: 1. Cookie翻译为小甜饼,有一种特殊的味道.cookie主要用来在(浏览器)客户端做记号用的.Cookie不属于java,Cookie是一种通用的机制,属于HTTP协议的一部 ...

  7. 浅谈 String 的 hashCode() 方法

    Java 中 hash 值的含义 hash 值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率,如HashMap.HashTable等: 如果两个对象相同,那么这两个对象的 hash ...

  8. [Android&amp;amp;Java]浅谈设计模式-代码篇:观察者模式Observer

    观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...

  9. 浅谈js的sort()方法

    如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码(字符串Unicode码点)的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以 ...

随机推荐

  1. sql server 读取excel里的数据

    以下是执行的sql代码,只拿简单读取数据举例,其他详细的,请自行查看 reconfigure RECONFIGURE GO GO SELECT * FROM OPENROWSET('Microsoft ...

  2. 《社交网络》里的评分公式——ELO排名系统

    <社交网络>里的Mark Zackburg被女朋友甩后,在舍友的启发下,充分发挥了技术宅男自娱自乐的恶搞天分,做出了Facemash网站,对学校女生的相貌进行排名打分,结果网站访问流量过大 ...

  3. CSS的压缩 方法与解压

    为什么要压缩CSS? 1.大网站节约流量 2.加快访问速度 工具:Dreamweaver(手工替换,个人感觉任何文本编辑器都可以)不过DW可以还原 CSS压缩与CSS代码压缩还原方法,CSS压缩工具有 ...

  4. 前端代码新写法——Zen Coding

    是不是还在为html繁琐的标签写法而苦恼? 是不是还在枯燥的写尖括号? Zen Coding的到来将让前端编码不在繁琐.不再拘泥html的尖括号和一堆一堆的标签. 先看看ZenCoding的效果图. ...

  5. Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)

    出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...

  6. ThinkPHP3.1新特性:命名范围

    概述 命名范围功能,给模型操作提供了一系列的(连贯操作)封装,让你更方便的查询和操作数据.我们来具体了解下这一用法. 定义属性 要使用命名范围功能,主要涉及到模型类的_scope属性定义和scope连 ...

  7. 爬取朋友圈,Get年度关键词

    人生苦短,我用Python && C#. 1.引言 最近初学Python,写爬虫上瘾.爬了豆瓣练手,又爬了公司的论坛生成词云分析年度关键词.最近琢磨着2017又仅剩两月了,我的年度关键 ...

  8. TIA Portal V13 WinCC中创建多语言项目

    1. 在项目树下选择“语言和资源”,双击打开“项目语言”,设置编辑语言和参考语言. 2. 在项目语言栏中勾选项目所需要的多种语言,我们以选择德语.英语和中文为例 3. 点击“参考语言”,切换语言为英语 ...

  9. js中,转义字符的表示

    HTML中<,>,&等有特殊含义(<,>,用于链接签,&用于转义),不能直接使用.这些符号是不显示在我们最终看到的网页里的,那如果我们希望在网页中显示这些符号, ...

  10. 文件夹放到VS2015显示不出来

    在该项目中,点这个按钮 , 会显示没有包括进项目的文件 在要包括的文件上右键--包括在项目中即可 同理也可以从项目排除