Закрытие источника потока

#java #xslt #java-ws

#java #xslt #java-ws

Вопрос:

Я получал сообщение об ошибке «слишком много открытых файлов» в своем веб-сервисе и просто хотел убедиться, что мне больше нечего закрывать. Я добавил close() on outWriter ( StringWriter ), но JavaDoc сказал, что это не имеет никакого эффекта. getCachedExtractSoapBodyXslt() возвращает javax.xml.transform.Transformer объект.

 String payload;
StreamResult result=null;
StringWriter outWriter=null;
try {
    // Programmatically extract the SOAP Body from message
    outWriter = new StringWriter();
    result = new StreamResult(outWriter);
    Source src = new StreamSource(new java.io.StringReader(doc));
    getCachedExtractSoapBodyXslt().transform(src, result);
    StringBuffer sb = outWriter.getBuffer();
    payload = sb.toString();
} catch (TransformerException e) {
    throw new ComponentException("Unable to extract SOAP Body");
}
finally {
    LOG.debug("Closing XSLT transformer output stream");
    try {
        outWriter.close();
    }
    catch (IOException e) {
        LOG.error("Failed to close stream for SOAP message");
    }
}
 

Комментарии:

1. В документации для StringWriter.close() указано, что это не имеет никакого эффекта. Документация для StringReader.close() не говорит ничего, кроме того, что говорит Reader.close() , но кажется маловероятным, что либо StringReader, либо StringWriter используют сокеты.

2. @VGR, Упс, я имел в виду слишком много открытых файлов, а не сокетов. Я обновил вопрос.

3. StringReader и StringWriter также не используют файлы, я почти уверен. Это может помочь изменить все использование потоков ввода, потоков вывода и каналов в вашей программе, чтобы использовать операторы try-with-resources , чтобы не было никаких шансов, что какие-либо из них остаются незакрытыми.

Ответ №1:

Мне пришлось переместить это в свою собственную переменную и закрыть ее

 new java.io.StringReader(doc)
 

Ответ №2:

StreamSource не имеет закрытия, и, по моим наблюдениям, его пользователи не закрывают поток или считыватель, который он содержит. И try-with-resource тоже не вариант, поскольку он не «закрывается». Поэтому пришлось пойти в старую школу и использовать try / finally, который вызывал методы getInputStream и getReader и передавал их результат в IOUtils.closeQuietly

 StreamSource source = null;
try {
   source = new StreamSource(inputStream);
   // Do stuff with source
}
finally {
   IOUtils.closeQuietly(source.getInputStream());
}
 

В моем случае мне действительно пришлось вызывать как getInputStream, так и getReader, поскольку мой исходный код был сконструирован двумя разными способами.