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.<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方法的更多相关文章
- 浅谈 js 字符串 trim 方法之正则篇
原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格 等 ...
- 浅谈 js 字符串 search 方法
原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...
- 浅谈 js 对象 toJSON 方法
前些天在<浅谈 JSON.stringify 方法>说了他的正确使用姿势,今天来说下 toJSON 方法吧.其实我觉得这货跟 toString 一个道理,他是给 stringify 方法字 ...
- JAVA IO流 InputStream流 Read方法
read()首先我们来看这个没有参数的read方法,从(来源)输入流中(读取的内容)读取数据的下一个字节到(去处)java程序内部中,返回值为0到255的int类型的值,返回值为字符的ACSII值(如 ...
- [iOS、Unity、Android] 浅谈闭包的使用方法
前言 我们经常所编程语言的的进步速度是落后于硬件的发展速度的. 但是最近几年,闭包语法在各个语言中都有自己的体现形式,例如 • C语言中使用函数指针作为回调函数的入口: • Java和C#语言中的La ...
- java 浅谈web系统当中的cookie和session会话机制
一 Cookie: 1. Cookie翻译为小甜饼,有一种特殊的味道.cookie主要用来在(浏览器)客户端做记号用的.Cookie不属于java,Cookie是一种通用的机制,属于HTTP协议的一部 ...
- 浅谈 String 的 hashCode() 方法
Java 中 hash 值的含义 hash 值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率,如HashMap.HashTable等: 如果两个对象相同,那么这两个对象的 hash ...
- [Android&Java]浅谈设计模式-代码篇:观察者模式Observer
观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...
- 浅谈js的sort()方法
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码(字符串Unicode码点)的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以 ...
随机推荐
- redis服务启动关闭脚本
代码如下: # chkconfig: 90 10 # description: service of redis for start and stop add by tomener PATH=/usr ...
- jfinal框架教程-学习笔记(一)
JFinal 是基于 Java 语言的极速 WEB + ORM 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java 语言所有优势 ...
- 庖丁解牛-----Live555源码彻底解密(RTP解包)
Live555 客户端解包 以testRTSPClient.cpp为例讲解: Medium<-MediaSource<-FramedSource<-RTPSource<-Mul ...
- web项目Log4j日志输出路径配置问题
问题描述:一个web项目想在一个tomcat下运行多个实例(通过修改war包名称的实现),然后每个实例都将日志输出到tomcat的logs目录下实例名命名的文件夹下进行区分查看每个实例日志,要求通过尽 ...
- [Everyday Mathematics]20150202
设 $f:\bbR^2\to \bbR$ 为连续函数, 且满足条件 $$\bex f(x+1,y)=f(x,y+1)=f(x,y),\quad\forall\ (x,y)\in \bbR^2. \ee ...
- util-C# 复杂条件查询(sql 复杂条件查询)查询解决方案
ylbtech-funcation-util: C# 复杂条件查询(sql 复杂条件查询)查询解决方案 C# 复杂条件查询(sql 复杂条件查询)查询解决方案 1.A,Ylbtech.Model返回 ...
- XSLT 调用java
XSLT调用JS http://www.ibm.com/developerworks/cn/xml/tips/x-tipxsltjs/index.htmlXSLT调用JAVA http://unm ...
- ACM2050
问题描述: 平面上有n条折线,问这些折线最多能将平面分割成多少块? 样例输入 1 2 样例输出 2 7 答案是: 2n ( 2n + 1 ) / 2 + 1 - 2n = 2 n^2 – n + ...
- [Hive - Tutorial] Data Units 数据存储单位
Data Units In the order of granularity - Hive data is organized into: 数据库.表.分区.桶 Databases: Namespac ...
- Java8新特性 1——利用流和Lambda表达式操作集合
Java8中可以用简洁的代码来操作集合,比如List,Map,他们的实现ArrayList.以此来实现Java8的充分利用CPU的目标. 流和Lambda表达式都是Java8中的新特性.流可以实现对集 ...