ColdFusion 11无法关闭java.io.FileInputStream

时间:2018-12-05 20:56:19

标签: coldfusion java-io coldfusion-11

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

我一切正常,但是文件不时被锁定,无法删除文件,并且在ColdFusion中收到以下错误。

  

ColdFusion无法删除文件C:/inetpub/mailroot/Queue/NTFS_AAAAAAAAAAAAAAAAAAAAA.EML。

这是我正在使用的代码

<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>

我忘了关闭其他任何东西,这就是为什么它导致文件被锁定吗?

1 个答案:

答案 0 :(得分:2)

FileInputStream的构造函数尝试打开文件流,因此它应成为try块的一部分。提醒:如果操作结果无法控制,请务必做好失败准备(例如,文件系统,数据库和网络)。您还需要确保无论打开文件流后如何关闭文件流,以确保文件句柄被释放。

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

  • 没有异常发生吗? finally最后执行。
  • 发生异常,执行了catch吗? finally最后执行。
  • 发生异常,catch没有涵盖该异常吗? finally最后执行。
  • 发生了异常,执行了catch,但是引发了另一个异常? finally最后执行。

但是,在执行finally时,您可能不知道有关文件流的确切情况(例如,甚至无法打开文件流,因此您将无法将其关闭)。因此,您仍然应该try来关闭流。

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

  

我注意到代码使用了这个。作用域,如果容器是存储在共享作用域(即竞争条件)中的cfc,则可能会产生问题。

是否有理由在fileSource范围内拥有this?您不应该将公共字段(this可以从组件外部访问)用作临时变量。