未关闭InputStream导致Tomcat意外死掉,重启后java.io.EOFException异常

问题背景:通过struts2 注解方式 实现zip文件下载

错误代码:

Struts 注解代码:

?

@Result(name = "downloadFile", type = StreamResult.class, value = "inputStream",params = {
            "contentType", "application/octet-stream",  
            "inputName", "inputStream",  
            "contentDisposition", "attachment;filename=\"${fileName}\"",  
            "bufferSize", "4096"})

?

inputStream的返回值方法:

?

?

/**
	 * 功能描述:返回下载文件流-另一种写法
	 * 注:此方法若不关闭返回的InputStream,则会导致Tomcat意外死掉
	 * @return
	 */
	public InputStream getInputStream() {
        String filePath = ServletActionContext.getServletContext().getRealPath("/downloadFile") + "//" + fileName;
        try {  
            setFileName(new String(fileName.getBytes(), "ISO-8859-1") );
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }
        try {
        	return new FileInputStream(filePath);// 直接将文件流返回
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
    }

?错误原因:将FileInputStream返回后,并没有将此stream close掉,需要说明的是程序里打开的文件IO资源不属于内存里的资源,而且java的垃圾回收机制也无法回收该资源,所有应该显示关闭文件IO资源。

?

修改后的代码:

/**
	 * 功能描述:返回下载文件流
	 * 注:此方法若不关闭返回的InputStream,则会导致Tomcat意外死掉
	 * @return
	 */
	public InputStream getInputStream() {
        String filePath = ServletActionContext.getServletContext().getRealPath("/downloadFile") + "//" + fileName;
        try {  
            setFileName(new String(fileName.getBytes(), "ISO-8859-1") );
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }
        InputStream stream = null;
        try {
//			return new FileInputStream(new File(filePath));
        	stream =  new FileInputStream(filePath);// 
        	return stream;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{// 正确写法必须要close inputStream
			try {
				stream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
    }

?若java的版本高于7(包括7),java7改写了所有的IO资源类,他们都实现了AutoCloseable接口,因此也可通过自动关闭资源的try语句来关闭这IO流。

?

?

?

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。