关闭被Struts流结果使用的FileInputStream

4

我的网页应用程序生成一个XML文件。我使用Struts2流结果来管理下载,这是在struts.xml中的操作:

<action name="generateXML" class="navigation.actions.GenerateXML">
    <result type="stream">
        <param name="contentType">text/xml</param>
        <param name="inputName">inputStream</param>
        <param name="bufferSize">1024</param>
    </result>
    ...
</action>

这是"GenerateXML"操作类的一部分,其中创建了FileInputStream "inputStream":
public String execute() {
    File xml = new File(filename);
    ...//fill the file with stuff
    try {
        setInputStream(new FileInputStream(xml));
    } finally {
        //inputStream.close();
        xml.delete();
    }
}

删除文件不起作用,因为inputStream尚未关闭(该部分已被注释掉)。但是,如果此时关闭它,则用户下载的xml文件为空,因为在struts生成下载之前已经关闭了其流。 除了使用定期删除服务器上的临时文件的脚本外,是否有一种方法可以在struts完成其操作后关闭“inputStream”?


1
Matthew的参考资料非常好。另一个选择是在invoke()之后的拦截器中进行文件清理。这可能更加可定制,尽管在这种情况下可能并不重要。 - Dave Newton
2个回答

3

没有关闭输入流时删除的方法,但你可以自己编写。请参见是否存在现有的FileInputStream在关闭时删除?

思路是不传递FileInputStream,而是传递ClosingFileInputStream,它会覆盖close并在调用close时删除文件。close()将由struts调用:

public String execute() {    
    File xml = new File(filename);
        ...//fill the file with stuff
        setInputStream(new ClosingFileInputStream(xml));   
    }

请查看链接中的问题获取更多信息。

3

您不需要这样做。Struts2将负责自行关闭流,您只需要创建一个输入流并设置即可。

以下是Struts2为您处理流关闭的方式:

public class StreamResult extends StrutsResultSupport {
  // removing all other code
      {
        // Flush
                oOutput.flush();
                }
                   finally {
                if (inputStream != null) inputStream.close();
                  if (oOutput != null) oOutput.close();
               }

    }

因为在Struts2中,流(stream)是一种结果类型,它的作用是从你定义的流中提取数据,刷新并关闭它。

我希望这能解决你的疑惑。


问题是,Struts 完成后,我就无法再控制使用该流的文件了,因此我无法删除它。Matthew 的解决方案有效。 - user1065335

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接