代码之家  ›  专栏  ›  技术社区  ›  Ennio

ColdFusion 11未关闭java.io.FileInputStream

  •  3
  • Ennio  · 技术社区  · 6 年前

    我在ColdFusion中有一个脚本正在读取一些文件 .EML

    我的一切工作正常,但有时文件会被锁定,我无法删除文件,我在ColdFusion中遇到以下错误。

    由于未知原因,ColdFusion无法删除文件C:/inetpub/mailroot/Queue/NTFS_aaaaaa.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 回复  |  直到 6 年前
        1
  •  2
  •   Alex    6 年前

    构造 FileInputStream 尝试打开文件流,因此它应该是您的 try 块提醒:如果操作结果超出您的控制范围(例如文件系统、数据库和网络),请始终做好失败准备。您还需要确保尽最大努力关闭文件流,不管打开文件流后发生了什么,以确保释放文件句柄。

    这就是问题所在 finally 尝试 catch

    • 没有发生异常? 最后
    • 发生异常, 抓住 最后 在最后执行。
    • 抓住 不包括例外情况吗?
    • 发生异常, 抓住 最后 在最后执行。

    最后 ,您可能不知道文件流的具体情况(例如,文件流一开始就无法打开,因此您也无法关闭)。所以你还是应该 关闭小溪。

    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 范围你不应该使用公共字段( 可以从组件外部访问)以获取临时变量。