`

jdk1.5下无法删除文件,file.delete方法失效

阅读更多
前几天在查看一从jdk1.4升迁到jdk1.5的系统时,发现本该被定时删除的excel文件全都还在原目录下面,真是奇怪.

出现问题的流程大致是:读取一系列的excel文件的信息存入数据库后,先把文件拷贝到备份目录,再删除源excel文件,该项目原先开发和部署环境(j2sdk1.4.2_12+jboss-4.0.5.GA)使用正常,文件也能正常被移动到备份目录,后在另一客户那里实施,换成了jdk1.5,因此我就用jdk1.5编译了一遍,没问题了,就给客户安装演示系统,因为读取excel数据一直都正常(从所导出的报表可得知),所以刚开始几天也没怎么关心这些excel文件是否正常被移动.

发现问题后赶紧debug跟踪,设置断点进行一步步查看,执行完file.delete()语句后,excel又可以被删除了,然后取消断点再运行,我靠,执行完delete()语句后,excel原封不动的待在那里.因为原来系统是运行正常的,于是重新编译部署在jdk1.4+jboss4.0下,运行正常.

真是奇怪了,同样的代码怎么会不一样呢,于是网上搜索关键字("java+java.io.file.delete()"),发现再sun论坛上也有人提出同样的问题,就是删除不了,且无任何错误提示,和我的情况一样,不过他的是jdk1.4下,跟帖的人问他输入流是否确定都close了,或者同时有人在占用该资源的引用,并且建议使用System.gc(),不过问题也没什么解决.后来又看了其他帖子,没什么建设性,索性回到项目源代码上,这是删除文件语句前的读取excel部分代码.

java 代码
  1.  jxl.Workbook rwb = null;   
  2.   
  3.    try{   
  4.      //构建Workbook对象, 只读Workbook对象   
  5.      //直接从本地文件创建Workbook   
  6.      //从输入流创建Workbook   
  7.        InputStream is  = new FileInputStream(fileAllName);   
  8.         
  9.      WorkbookSettings workbookSettings=new WorkbookSettings();   
  10.      //workbookSettings.setLocale(new Locale("zh","CN"));      
  11.   
  12.     // workbookSettings.setEncoding("ISO-8859-1");    
  13.      workbookSettings.setEncoding("GBK");   
  14.      rwb = Workbook.getWorkbook(is,workbookSettings);   
  15.   
  16.      //Sheet(术语:工作表)就是Excel表格左下角的Sheet1,Sheet2,Sheet3但在程序中   
  17.      //Sheet的下标是从0开始   
  18.      //获取第一张Sheet表   
  19.       Sheet rs = rwb.getSheet(0);   
  20.       //获取Sheet表中所包含的总列数   
  21.       int rsColumns = rs.getColumns();   
  22.       //获取Sheet表中所包含的总行数   
  23.       int rsRows = rs.getRows();   
  24.       ..............省略..........   
  25.        
  26.       //读取行信息   
  27.           
  28.        
  29.   
  30.   
  31.    }catch(Exception e)   
  32. {   
  33.    }   
  34.    finally{   
  35.      //操作完成时,关闭对象,释放占用的内存空间   
  36.      rwb.close();   
  37.  }  

该代码在jdk1.4下运行正常,按道理该释放的都释放了,联想到搜索资料上多次提及的未释放资源,我把注意力放在了该段代码的7.InputStream is  = new FileInputStream(fileAllName);   上,这个输入流却没有放进finally区,照此思路,我把代码改成了下面这个样子

java 代码
  1. jxl.Workbook rwb = null;   
  2. InputStream is  = null;   
  3.   try{   
  4.     //构建Workbook对象, 只读Workbook对象   
  5.     //直接从本地文件创建Workbook   
  6.     //从输入流创建Workbook   
  7.       is  = new FileInputStream(fileAllName);   
  8.        
  9.     WorkbookSettings workbookSettings=new WorkbookSettings();   
  10.     //workbookSettings.setLocale(new Locale("zh","CN"));      
  11.   
  12.    // workbookSettings.setEncoding("ISO-8859-1");    
  13.     workbookSettings.setEncoding("GBK");   
  14.     rwb = Workbook.getWorkbook(is,workbookSettings);   
  15.   
  16.     //Sheet(术语:工作表)就是Excel表格左下角的Sheet1,Sheet2,Sheet3但在程序中   
  17.     //Sheet的下标是从0开始   
  18.     //获取第一张Sheet表   
  19.      Sheet rs = rwb.getSheet(0);   
  20.      //获取Sheet表中所包含的总列数   
  21.      int rsColumns = rs.getColumns();   
  22.      //获取Sheet表中所包含的总行数   
  23.      int rsRows = rs.getRows();   
  24.      ..............省略..........   
  25.       
  26.      //读取行信息   
  27.          
  28.       
  29.   
  30.   
  31.   }catch(Exception e)   
  32.   
  33.   }   
  34.   finally{   
  35.     //操作完成时,关闭对象,释放占用的内存空间   
  36.     rwb.close();   
  37.     try  
  38.     {   
  39.       is.close();   
  40.     }   
  41.     catch(Exception e){}   
  42.   }  

也就是将is也显性的立即释放掉,在j2sdk1.5.0_13+jboss-4.2.0.GA上运行,excel被成功删除,后更新到客户演示环境,也成功了.

究其原因,我估计是jdk1.4和jdk1.5在垃圾回收策略上的不同,在jdk1.4上,is在rwb.close();后就被释放掉了,而在1.5上则有些延迟,这也能解释为何我在jdk1.5上设置断点进行单步跟踪(相当于sheep())的时候能删除,当然,原来代码本身写得也不规范,is应该要被显性释放.

分享到:
评论

相关推荐

    Java利用WatchService监听文件变化示例

    下面是一个具体的代码示例,演示了如何利用WatchService来监听指定目录下文件的变化,并在控制台打印出相应的事件信息。这是一个测试程序,当你运行它时,它会监视目录d:/test下发生的所有文件变化事件,并在控制台...

    1剑盛二面准备试题.txt1剑盛二面准备试题.txt

    17. **Files类的常用方法**:Files是java.nio.file包中的类,提供了文件操作的常用方法,如exists()检查文件是否存在,readAllBytes()读取文件的所有字节,delete()删除文件,copy()复制文件,move()移动文件等。...

    Jsp程序设计复习试题.pdf

    15. 文件操作:File对象的delete()方法可以删除文件,但不能删除包含文件的目录。选项C错误。 16. 更新数据库记录:执行更新操作,如更新字段值,应使用Statement对象的executeUpdate()方法。选项B正确。 17. 使用...

    2022最新Java面试题常见面试题与答案汇总0001.pdf

    14. `File`类常用方法包括`exists()`、`mkdirs()`、`delete()`、`getName()`等。 二、容器 1. Java容器主要包括`Collection`、`List`、`Set`和`Map`。 2. `Collection`是所有单列集合的父接口,`List`和`Set`都是其...

    良心出品Jsp程序设计复习答案.doc

    14. **File对象的delete()方法**:File对象的delete()方法可以删除文件或空目录,但不能删除非空目录,所以C选项错误。 15. **数据库操作**:对数据库记录字段值更新通常使用executeUpdate()方法,对应B选项。 16....

    installanywhere2009 打包j2ee工程全程图解

    关键的一环是加载工程内容,特别是包含main方法的jar包,这有助于加速main文件的搜索。同时,你还可以设置应用程序的图标,提升用户体验。对于纯J2EE工程,如果不涉及桌面应用,可以省略设置图标这一步。 接着,...

    JavaEE技术问题汇总.docx

    【Java深复制与浅复制】 ...以上仅是部分知识点,更多如静态代理、动态代理、CGLIB与JDK代理、静态关键字、CAS单点登录原理等未展开详述。这些知识涵盖JavaEE开发的多个方面,对于理解和优化JavaEE应用至关重要。

Global site tag (gtag.js) - Google Analytics