ColdFusion 11 没有关闭 java.io.FileInputStream

标签 coldfusion java-io coldfusion-11

我在 ColdFusion 中有一个脚本,它正在从本地 SMTP 服务器读取一些文件 .EML 并从文件中提取一些数据。

我一切正常,但有时文件会被锁定,我无法删除文件,并且在 ColdFusion 中出现以下错误。

ColdFusion could not delete the file C:/inetpub/mailroot/Queue/NTFS_AAAAAAAAAAAAAAAAAA.EML for an unknown reason.

这是我使用的代码

<cfscript>
props = createObject("java", "java.lang.System").getProperties();

props.put( javacast("string", "mail.host"), javacast("string", "localhost"));
props.put( javacast("string", "mail.transport.protocol"),  javacast("string", "smtp"));

mailSession = createObject("java", "javax.mail.Session").getDefaultInstance(props, javacast("null", ""));

fileList = directoryList('C:\inetpub\mailroot\Queue\');

for (x=1; x LTE ArrayLen(fileList); x=x+1) {
    pathToEmailFile = fileList[x];

    this.fileSource = createObject("java", "java.io.FileInputStream").init(pathToEmailFile);

    try {
        message = createObject("java", "javax.mail.internet.MimeMessage").init(mailSession, this.fileSource);

        bodyData = message.getContent();
        bodyPart = bodyData.getBodyPart(javacast("int", 0)).getContent();
        from = reMatchNoCase('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,63}', message.getFrom()[1].toString())[1];
        subject = message.getSubject();

        // CALL FUNCTION TO PROCESS DATA HERE
    } catch (any e) {
        // CLOSE THE FILE IF THERE IS ANY ERROR
        this.fileSource.close();
        writeDump(e);
    }
    this.fileSource.close();
    fileDelete(pathToEmailFile);
}
</cfscript>

我是否忘记关闭其他任何东西,这就是导致文件被锁定的原因?

最佳答案

FileInputStream 的构造函数尝试打开一个文件流,因此它应该是您的 try block 的一部分。提醒:如果操作的结果不在您的手中(例如文件系统、数据库和网络),请始终为失败做好准备。您还需要确保尽可能关闭文件流,无论打开它后发生了什么,以确保释放文件句柄。

这就是 finally block 的用途。无论 trycatch block 中发生什么,都会执行此 block 。

  • 没有发生异常? finally在最后执行。
  • 异常发生,catch被执行? finally在最后执行。
  • 发生异常,catch 没有覆盖异常? finally在最后执行。
  • 发生异常,执行了catch,但抛出另一个异常? finally在最后执行。

但是,当执行 finally 时,您可能不知道关于文件流的确切情况(例如,文件流甚至无法打开,所以您不会也可以关闭它)。因此,您仍然应该尝试关闭流。

for (x=1; x LTE ArrayLen(fileList); x=x+1) {
    pathToEmailFile = fileList[x];

    deleteFile = false;

    try {
        this.fileSource = createObject("java", "java.io.FileInputStream").init(pathToEmailFile);
        // your extraction code...
        deleteFile = true; // extraction succeeded, delete file after releasing it
    } catch (any e) {
        // log the exception
    } finally {
        // try to close the file stream
        try {
            this.fileSource.close();
        } catch (any e) {
            // file stream was probably not even opened
        }
    }

    if (deleteFile) {
        try {
            fileDelete(pathToEmailFile);
        } catch (any e) {
            // file could not be deleted, probably for the same reasons it failed previously
        }
    }
}

无论提取结果如何,我不确定您是否真的打算删除该文件,因此我为此添加了逻辑,您自己决定。

此外,Ageax正确观察:

I noticed the code uses this. scope, which might create a problem if the container is a cfc stored in a shared scope i.e. race conditions.

this 范围内有 fileSource 是有原因的吗?您不应该为临时变量使用公共(public)字段(this 可以从组件外部访问)。

关于ColdFusion 11 没有关闭 java.io.FileInputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53640604/

相关文章:

javascript - 与服务器端和客户端验证冲突

coldfusion - 执行锁定步骤后无法更新 ColdFusion

Apache 在使用 mod_proxy 时忽略重写规则

mysql - 找不到 Coldfusion EntityLoad get 方法,但使用 EntityLoadByPK 时,get 方法可以工作

mysql - ColdFusion cfdump 不显示对 Lucee 版本 5.2.1.9 的查询

jquery - 如果 x=true,则将项目移动到 <cfloop> 中的第一个数组位置

java - 在 Java ME 中找不到 FileReader

xml - 引用节点值时包含 ColdFusion 11 xml 标记

java - Path.toFile() 和 new File(pathString) 的不同行为

java.io.IOException : Stream closed at java. util.zip.ZipInputStream.ensureOpen(ZipInputStream.java:66)