FileInputStream未关闭

时间:2016-03-18 06:42:52

标签: java apache-poi

我有以下代码来设置Excel文件:

public static void setExcelFile(String Path) throws Exception {
    try {
        FileInputStream ExcelFile = new FileInputStream(Path);
        ExcelWBook = new XSSFWorkbook(ExcelFile);
    } catch (Exception e){
        Log.error("Class Utils | Method setExcelFile | Exception desc : "+e.getMessage());
    }
}

这将从另一个类的循环中调用。将对位置中的每个Excel文件重复此循环。我是否需要每次为每个Excel文件关闭FileInputStream?如果我没有在每个Excel文件的末尾关闭。它会对内存利用率产生影响吗?或者,每次为下一个Excel文件创建新的Filestream对象时,它是否会自动关闭前一个文件并为当前文件创建?我遇到了以下错误消息的问题。

Exception in thread "main" java.lang.reflect.InvocationTargetException
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.OutOfMemoryError: Java heap space
  at org.apache.xmlbeans.impl.store.Cur.createElementXobj(Cur.java:260)
  at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.startElement(Cur.java:2997)
  at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3211)
  at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java:1082)
  at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1822)
  at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521)
  at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseTagNS(PiccoloLexer.java:1362)
  at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:4682)
  at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290)
  at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400)
  at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714)
  at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3479)
  at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1277)
  at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1264)
  at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
  at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
  at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:194)
  at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:186)
  at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:354)
  at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:166)
  at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:263)
  at utility...

4 个答案:

答案 0 :(得分:2)

您应该在catch块中添加ExcelFile.close() [ref]并在使用完资源后添加。这样做是为了防止内存泄漏,在您的情况下是例外。

答案 1 :(得分:2)

如果不关闭流,文件将被锁定,直到输入流已关闭或JVM关闭。您应该关闭流,否则您可能会在下次从java读取该文件或直接使用Windows

时遇到IOException

答案 2 :(得分:2)

来自XSSFWorkbook(InputStream)

  

构造一个XSSFWorkbook对象,将整个流缓冲到内存中,然后为它打开一个OPCPackage对象。

     

使用InputStream比使用文件需要更多内存,因此如果File可用,那么您应该执行类似

的操作
       OPCPackage pkg = OPCPackage.open(path);
       XSSFWorkbook wb = new XSSFWorkbook(pkg);
       // work with the wb object
       ......
       pkg.close(); // gracefully closes the underlying zip file

由于您有路径字符串,因此应使用XSSFWorkbook(File)XSSFWorkbook(String)

关闭资源:Always close streams。来自Java Practices -> Recovering resources

  

应该通过明确调用为此目的定义的清理方法,尽快回收昂贵的资源。如果不这样做,那么系统性能会降低。在最糟糕的情况下,系统甚至可能完全失败。

     

资源包括:

     
      
  • 输入输出流
  •   
  • 数据库结果集,语句和连接
  •   
  • 线程
  •   
  • 图形资源
  •   
  • 插座
  •   

答案 3 :(得分:0)

正如其他人已经告诉过你的那样:是的,你总是应该关闭这些流。此外,每个未闭合和未定型的流将在某些系统上保留文件句柄,并且您可能会遇到每个进程的总最大值。 (这取决于您的操作系统。)

上面的上下文中最简单的事情可能是使用try-with-resources结构自动关闭:

try (
   FileInputStream ExcelFile = new FileInputStream(Path);
) {
  ExcelWBook = new XSSFWorkbook(ExcelFile);
} catch (Exception e) {
  Log.error("Class Utils | Method setExcelFile | Exception desc : "+ e.getMessage());
}