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

在从JDK1.4升级到JDK1.5的过程中,遇到原本能够正常删除的Excel文件无法删除的问题。通过逐步排查,发现是由于文件输入流未正确关闭导致。最终通过改进代码确保所有资源都被正确释放,解决了该问题。
前几天在查看一从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应该要被显性释放.

// Top-level build file where you can add configuration options common to all sub-projects/modules. final javaVerProp = System.getProperty("java.version") println("CI runtime info: java.version=$javaVerProp") final javaVersion = javaVerProp.split("\\.")[0].toInteger() final requireJava = prop_targetCompatibility.toInteger() if (javaVersion < requireJava) { final errMsg = "Require to run gradle with java version at least $requireJava, " + "but current java version is $javaVersion. Please update project gralde JDK configs!" throw new IllegalStateException(errMsg) } buildscript { repositories { maven { url prop_oppoMavenUrl allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } maven { url prop_oppoTestMavenUrl allowInsecureProtocol = true } maven { url prop_oapm_oppoMavenUrl allowInsecureProtocol = true } maven { url prop_synergySdkMavenUrl allowInsecureProtocol = true } maven { url prop_sdkMavenUrlRelease allowInsecureProtocol = true } maven { url prop_oppoBrowserMavenUrl allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } maven { // accountSdk url prop_nexusReleaseUrl allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } maven { url prop_oppoMavenUrlSnapshot allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } } dependencies { // commons-io:2.15.1、commons-logging:1.3.0、slf4j-api:2.0.10 编译依赖 r8 新版本, AGP 升级到 8.2.0 后可以去掉该配置 classpath libs.android.tools.r8 classpath libs.android.gradle.plugin classpath libs.oplus.oapm.plugin classpath libs.kotlin.gradle.plugin classpath libs.kotlin.serialization.plugin classpath libs.oplus.build.plugin classpath libs.google.protobuf.plugin classpath "com.autotest.opasm:CoverageInstPlugin:1.9.18-SNAPSHOT" } } allprojects { repositories { maven { url prop_oppoMavenUrl allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } maven { url prop_oapm_oppoMavenUrl allowInsecureProtocol = true } maven { url prop_sdkMavenUrlRelease allowInsecureProtocol = true } maven { url prop_nexusReleaseUrl allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } maven { url prop_oppoMavenUrlSnapshot allowInsecureProtocol = true credentials { username sonatypeUsername password sonatypePassword } } //Jacoco覆盖率插桩: Maven BranchIO maven { url prop_oppoMavenUrlBranchIO allowInsecureProtocol = true } //Jacoco覆盖率插桩: Maven Snapshots maven { url prop_oppoMavenUrlSnapshots allowInsecureProtocol = true } } } tasks.register('clean', Delete) { delete rootProject.buildDir delete file("${rootDir}/reports") delete file("${rootDir}/UnitTestReport") delete file("${rootDir}/jacocoinfo.txt") } apply from: rootProject.file("scripts/rootPrjConfigs.gradle")这是全局的gradle配置
最新发布
07-19
Properties properties = new Properties() properties.load(project.file('info.properties').newDataInputStream()) def profile = project.hasProperty('profile')? project['profile'] : 'dev' def artifact_type = '' if(profile == 'dev') { artifact_type = '-SNAPSHOT' } version = properties.getProperty("artifact_version")+artifact_type buildscript { repositories { maven { url = 'http://maven.xylink.com:8081/nexus/content/groups/public/' } } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'maven' apply plugin: 'maven-publish' sourceCompatibility = 1.8 targetCompatibility = 1.8 sourceSets { main.resources.srcDirs = ["src/main/java"] main.resources.includes = [ "**/*.json" ] } repositories { maven { url = 'http://maven.xylink.com:8081/nexus/content/groups/public/' } } jar { baseName 'xylink-cloudsdk' } dependencies { compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.2' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' compile group: 'log4j', name: 'log4j', version: '1.2.17' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.3' compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.3' compile("org.apache.httpcomponents:httpclient:4.3.5") compile("commons-httpclient:commons-httpclient:3.1") compile("org.apache.commons:commons-lang3:3.3.2") compile("com.belerweb:pinyin4j:2.5.0") compile group: 'commons-codec', name: 'commons-codec', version: '1.15' compile('org.bouncycastle:bcprov-jdk15on:1.57') compile('com.google.guava:guava:31.1-jre') testCompile("junit:junit:4.12") } //执行build后自动执行任务,打包 this.afterEvaluate { Project project -> // 找到 build task def buildTask = project.tasks.getByName('build') if (buildTask == null) { throw GradleException("build task is not found.") } // 执行 build task 之后的 packageForPublish buildTask.finalizedBy "packageForPublish" } //自动挑出需要的文件打包成zip包 task packageForPublish(type: Zip) { doLast { println "packageForPublish" } includeEmptyDirs = false delete("build/libs/cloudsdk") delete("build/libs/cloudsdk.zip") archiveName "cloudsdk.zip" destinationDir file('build/libs/') from('./') { include 'src/**' include 'build.gradle' include 'readme.txt' include 'settings.gradle' exclude '**/test/java/com/xylink/sdk/**' into 'cloudsdk' } } //替换版本号到SDKConfigMgr fileTree(project.getProjectDir()).each { if(it.isFile() && it.name.endsWith(".java") && it.name.startsWith("SDKConfigMgr")){ def content = fileReader(it.absolutePath, "private static String sdkjarVersion", " private static String sdkjarVersion = \"$version\";") fileWrite(it.absolutePath, content) return } } //读取文件并替换字符串 def fileReader(path, keyword, newString) { def readerString = ""; new File(path).withReader('UTF-8') { reader -> reader.eachLine { if (it.contains(keyword)) { it = it.replace(it, newString) } readerString <<= it readerString << '\n' } return readerString } } //写入文件 def fileWrite(path, content) { new File(path).withWriter('UTF-8') { writer -> writer.append(content) } } 修复一下
03-08
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值