ColdFusion 11 未关闭 java.io.FileInputStream
ColdFusion 11 not closing java.io.FileInputStream
我在 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
块的一部分。提醒:如果操作的结果不在您的手中(例如文件系统、数据库和网络),请始终为失败做好准备。您还需要确保尽可能关闭文件流,无论打开后发生什么情况,以确保释放文件句柄。
这就是 finally
块的用途。无论 try
和 catch
块中发生什么,都会执行此块。
- 没有异常发生?
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 正确观察到:
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 中有一个脚本,它正在从本地 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
块的一部分。提醒:如果操作的结果不在您的手中(例如文件系统、数据库和网络),请始终为失败做好准备。您还需要确保尽可能关闭文件流,无论打开后发生什么情况,以确保释放文件句柄。
这就是 finally
块的用途。无论 try
和 catch
块中发生什么,都会执行此块。
- 没有异常发生?
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 正确观察到:
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
可以从组件外部访问)作为临时变量。