【问题标题】:Django - HTTPStream of gzip file creaed on the flyDjango - 动态创建的 gzip 文件的 HTTPStream
【发布时间】:2014-08-18 13:36:52
【问题描述】:

我使用 StringIO 创建了一个包含 xml 数据的文件对象,然后我用这个文件对象创建了一个 gzip 文件,我在使用 django 通过 HTTP 制作这个流时遇到了问题,文件大小并不总是固定的,有时它可能很大,这就是为什么我选择 HTTPStream 而不是普通的 HTTP 响应。我不知道如何发送文件长度,因为文件对象不可搜索。

谢谢你的帮助,干杯!

这是我的代码:

# Get the XML string
xml_string = get_xml_cebd(cebds)

# Write the xml string to the string io holder
cebd_xml_file.write(xml_string)

# Flush the xml file buffer
cebd_xml_file.flush()

# Create the Gzip file handler, with the StringIO in the fileobj
gzip_handler = gzip.GzipFile(
    fileobj=cebd_xml_file,
    filename=base_file_name + '.xml',
    mode='wb'
)

# Write the XML data into the gziped file
gzip_handler.write(cebd_xml_file.getvalue())
gzip_handler.flush()

# Generate the response using the file warpper, content type: x-gzip
# Since this file can be big, best to use the StreamingHTTPResponse
# that way we can garantee that the file will be sent entirely
response = StreamingHttpResponse(
    gzip_handler,
    content_type='application/x-gzip'
)

# Add content disposition so the browser will download the file
response['Content-Disposition'] = ('attachment; filename=' +
    base_file_name + '.xml.gz')

# Content size
gzip_handler.seek(0, os.SEEK_END)
response['Content-Length'] = gzip_handler.tell()

【问题讨论】:

    标签: python django gzip http-streaming


    【解决方案1】:

    我找到了解决这两个问题的方法,应该传递给 HTTPStream 的处理程序是 StringIO 处理程序,而不是 Gzip 处理程序,StringIO 处理程序也是可搜索的,这样我就可以在之后检查数据的大小gzipped,另一个技巧是在 gzip 处理程序上调用 close 方法,以便它将 crc32 和大小添加到 gzip 文件中,否则发送的数据将为 0,因为 StringIO 不要调用 close 方法,因为 HTTPStream 将需要处理程序打开以流式传输数据,垃圾收集器将在流完成后将其关闭。

    这是最终代码:

    # Use cStringIO to create the file on the fly
    cebd_xml_file = StringIO.StringIO()
    
    # Create the file name ...
    base_file_name = "cebd"
    
    # Get the XML String
    xml_string = get_xml_cebd(cebds)
    
    # Create the Gzip file handler, with the StringIO in the fileobj
    gzip_handler = gzip.GzipFile(
        fileobj=cebd_xml_file,
        filename=base_file_name + '.xml',
        mode='wb'
    )
    
    # Write the XML data into the gziped file
    gzip_handler.write(xml_string)
    
    # Flush the data
    gzip_handler.flush()
    
    # Close the Gzip handler, the close method will add the CRC32 and the size
    gzip_handler.close()
    
    # Generate the response using the file warpper, content type: x-gzip
    # Since this file can be big, best to use the StreamingHTTPResponse
    # that way we can garantee that the file will be sent entirely
    response = StreamingHttpResponse(
        cebd_xml_file.getvalue(),
        content_type='application/x-gzip'
    )
    
    # Add content disposition so the browser will download the file, don't use mime type !
    response['Content-Disposition'] = ('attachment; filename=' +
        base_file_name + '.xml.gz')
    
    # Content size
    cebd_xml_file.seek(0, os.SEEK_END)
    response['Content-Length'] = cebd_xml_file.tell()
    
    # Send back the response to the request, don't close the StringIO handler !
    return response
    

    干杯,希望这可以帮助任何人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多