Primefaces在读取后不会立即关闭DefaultStreamedContent流

时间:2013-08-23 10:04:09

标签: jsf file-io primefaces stream

我有以下问题:

我使用Primefaces中的<p:graphicImage>在我的网络应用中显示图像

显示的图像由bean作为DefaultStreamedContent传送。在我的应用程序中,我有时会删除运行时以这种方式显示的图像

这总是需要一点时间,直到我可以删除图像。经过调试后,我使用了Java 7的Files.delete并得到了以下异常:

The process cannot access the file because it is being used by another process.

因此我怀疑Primefaces在显示后没有立即关闭DefaultStreamedContent后面的流,我无法随时删除文件。

有没有办法告诉DefaultStreamedContent在阅读后立即关闭自己(我已经查看了文档并且在DefaultStreamedContent内没有找到任何合适的方法,但也许可以告诉流或类似的东西?)

1 个答案:

答案 0 :(得分:4)

好的,我终于找到了使用Unlocker工具

发生的事情

(可以在这里下载:http://www.emptyloop.com/unlocker/#download

我看到java.exe一旦显示就锁定了文件。因此,Stream后面的StreamedContent在阅读后不会立即关闭。

我的解决方案如下:

我创建了一个扩展StreamedContent的超类,让它读取输入流并将读取的字节“提供”到新的InputStream。之后,我关闭了给定的流,以便再次释放它背后的资源。

这个类看起来像这样:

public class PersonalStreamedContent extends DefaultStreamedContent {

/**
 * Copies the given Inputstream and closes it afterwards
 */
public PersonalStreamedContent(FileInputStream stream, String contentType) {
    super(copyInputStream(stream), contentType);
}

public static InputStream copyInputStream(InputStream stream) {
    if (stream != null) {
        try {
            byte[] bytes = IOUtils.toByteArray(stream);
            stream.close();
            return new ByteArrayInputStream(bytes);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        System.out.println("inputStream was null");
    }
    return new ByteArrayInputStream(new byte[] {});
}
}

我非常确定Primefaces检索到的图像是2次,但只在第一次加载时关闭。我一开始并没有意识到这一点。

我希望这也可以帮助其他人:)