ColdFusion 11 не закрывает java.io.FileInputStream - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть скрипт в ColdFusion, который читает некоторые файлы .EML с локального SMTP-сервера и извлекает некоторые данные из файлов.

У меня все работает нормально, но время от времени файлы получаютзаблокирован, и я не могу удалить файл, и я получаю следующую ошибку в ColdFusion.

ColdFusion не удалось удалить файл C: /inetpub/mailroot/Queue/NTFS_AAAAAAAAAAAAAAAAAA.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 голосов
/ 07 декабря 2018

Конструктор 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 правильно соблюдается:

Я заметил, что код использует это.область действия, которая может создать проблему, если контейнер является cfc, хранящимся в общей области, то есть в условиях гонки.

Есть ли причина для наличия fileSource в области действия this?Вы не должны использовать открытое поле (this может иметь доступ извне компонента) для временной переменной.

...