Groovy Grails,如何在控制器的响应中流式传输或缓冲大文件?

Posted

技术标签:

【中文标题】Groovy Grails,如何在控制器的响应中流式传输或缓冲大文件?【英文标题】:Groovy Grails, How do you stream or buffer a large file in a Controller's response? 【发布时间】:2011-02-18 22:48:06 【问题描述】:

我有一个控制器,它连接到一个 url 以检索一个 csv 文件。

我可以使用以下代码在响应中发送文件,这工作正常。

    def fileURL = "www.mysite.com/input.csv"
    def thisUrl = new URL(fileURL);
    def connection = thisUrl.openConnection();
    def output = connection.content.text;

    response.setHeader "Content-disposition", "attachment;
    filename=$'output.csv'"
    response.contentType = 'text/csv'
    response.outputStream << output
    response.outputStream.flush()

但是我认为这种方法不适合大文件,因为整个文件都会加载到控制器内存中。

我希望能够逐块读取文件并将文件逐块写入响应块。

有什么想法吗?

【问题讨论】:

【参考方案1】:

Groovy OutputStreams 可以使用 &lt;&lt; 运算符直接获取 InputStreams。 OutputStream 将使用适当大小的缓冲区自动提取数据。

即使 CSV 非常大,以下内容也应该可以有效地复制数据。

def fileURL = "www.mysite.com/input.csv"
def thisUrl = new URL(fileURL);
def connection = thisUrl.openConnection();
def cvsInputStream = connection.inputStream

response.setHeader "Content-disposition", "attachment;
filename=$'output.csv'"
response.contentType = 'text/csv'
response.outputStream << csvInputStream
response.outputStream.flush()

【讨论】:

很好的解决方案,但也要记得关闭 inputStream。一个安全的替代方法是使用 connection.withInputStream...

以上是关于Groovy Grails,如何在控制器的响应中流式传输或缓冲大文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Grails 控制器之间传递错误消息?

Groovy/grails 如何使用 jquery 从视图中调用控制器方法

在 grails 应用程序中在运行时修改 groovy 代码

Grails:服务 VS Groovy 类

Groovy Grails 处理控制器参数

如何将 Grails 服务注入 src/groovy 类