使用 Python 在演示文稿中管理 BLOB 以实现高效内存使用

关于 BLOB

BLOBBinary Large Object)通常是以二进制格式保存的大型项目(照片、演示文稿、文档或媒体)。

Aspose.Slides for Python via .NET 允许您以一种在涉及大型文件时降低内存消耗的方式为对象使用 BLOB。

使用 BLOB 降低内存消耗

通过 BLOB 将大文件添加到演示文稿

Aspose.Slides for .NET 允许您通过涉及 BLOB 的流程添加大文件(本例中为大型视频文件),以降低内存消耗。

以下 Python 示例演示了如何通过 BLOB 过程将大型视频文件添加到演示文稿:

import aspose.slides as slides

pathToVeryLargeVideo = "veryLargeVideo.avi"

# 创建一个将添加视频的新演示文稿
with slides.Presentation() as pres:
    with open(pathToVeryLargeVideo, "br") as fileStream:
        # 我们将视频添加到演示文稿中——我们选择了 KeepLocked 行为,因为我们
        # 不打算访问 "veryLargeVideo.avi" 文件。
        video = pres.videos.add_video(fileStream, slides.LoadingStreamBehavior.KEEP_LOCKED)
        pres.slides[0].shapes.add_video_frame(0, 0, 480, 270, video)

        # 保存演示文稿。即使输出大型演示文稿,内存消耗
        # 在 pres 对象的整个生命周期中仍保持较低 
        pres.save("presentationWithLargeVideo.pptx", slides.export.SaveFormat.PPTX)

通过 BLOB 从演示文稿导出大文件

Aspose.Slides for Python via .NET 允许您通过涉及 BLOB 的流程从演示文稿中导出大文件(本例中为音频或视频文件)。例如,您可能需要从演示文稿中提取大型媒体文件,但不希望该文件加载到计算机内存中。通过 BLOB 过程导出文件,可保持低内存消耗。

以下 Python 代码演示了上述操作:

import aspose.slides as slides

loadOptions = slides.LoadOptions()
loadOptions.blob_management_options = slides.BlobManagementOptions()
loadOptions.blob_management_options.presentation_locking_behavior = slides.PresentationLockingBehavior.KEEP_LOCKED
loadOptions.blob_management_options.is_temporary_files_allowed = True

with slides.Presentation(path + "Video.pptx", loadOptions) as pres:
	# 将每个视频保存为文件。为防止高内存使用,我们需要一个用于
	# 将演示文稿的视频流数据传输到新创建的视频文件流的缓冲区。
	# byte[] buffer = new byte[8 * 1024];
    bufferSize = 8 * 1024

	# 遍历视频
    index = 0
    # 如有需要,您可以对音频文件执行相同的步骤。 
    for video in pres.videos:
		# 打开演示文稿的视频流。请注意,我们故意避免访问属性
		# 如 video.BinaryData —— 因为该属性返回包含完整视频的字节数组,进而
		# 导致字节被加载到内存中。我们使用 video.GetStream,它将返回 Stream —— 并且不会
		#  要求我们将整个视频加载到内存中。
        with video.get_stream() as presVideoStream:
            with open("video{index}.avi".format(index = index), "wb") as outputFileStream:
                buffer = presVideoStream.read(8 * 1024)
                bytesRead = len(buffer)
                while bytesRead > 0:
                    outputFileStream.write(buffer)
                    buffer = presVideoStream.read(8 * 1024)
                    bytesRead = len(buffer)
                    
        index += 1

在演示文稿中将图像添加为 BLOB

使用 ImageCollection 类的方法,您可以将大型图像作为流添加,以使其被视为 BLOB。

以下 Python 代码演示了如何通过 BLOB 过程添加大型图像:

import aspose.slides as slides

# 创建一个将添加图像的新演示文稿。
with slides.Presentation() as pres:
    with open("img.jpeg", "br") as fileStream:
        img = pres.images.add_image(fileStream, slides.LoadingStreamBehavior.KEEP_LOCKED)
        pres.slides[0].shapes.add_picture_frame(slides.ShapeType.RECTANGLE, 0, 0, 300, 200, img)
    pres.save("presentationWithLargeImage.pptx", slides.export.SaveFormat.PPTX)

内存与大型演示文稿

通常,要加载大型演示文稿,计算机需要大量临时内存。演示文稿的所有内容都会加载到内存中,而加载该演示文稿的文件则不再使用。

以包含 1.5 GB 视频文件的大型 PowerPoint 演示文稿(large.pptx)为例。加载演示文稿的标准方法在以下 Python 代码中描述:

import aspose.slides as slides

with slides.Presentation("large.pptx") as pres:
	pres.save("large.pdf", slides.export.SaveFormat.PDF)

但此方法会消耗约 1.6 GB 的临时内存。

将大型演示文稿作为 BLOB 加载

通过涉及 BLOB 的流程,您可以在使用极少内存的情况下加载大型演示文稿。以下 Python 代码描述了使用 BLOB 流程加载大型演示文稿文件(large.pptx)的实现:

import aspose.slides as slides

loadOptions = slides.LoadOptions()
loadOptions.blob_management_options = slides.BlobManagementOptions()
loadOptions.blob_management_options.presentation_locking_behavior = slides.PresentationLockingBehavior.KEEP_LOCKED
loadOptions.blob_management_options.is_temporary_files_allowed = True

with slides.Presentation("large.pptx", loadOptions) as pres:
	pres.save("large.pdf", slides.export.SaveFormat.PDF)

更改临时文件夹

使用 BLOB 流程时,计算机会在默认的临时文件夹中创建临时文件。如果希望将临时文件保存在其他文件夹,可以使用 temp_files_root_path 更改存储设置:

import aspose.slides as slides

loadOptions = slides.LoadOptions()
loadOptions.blob_management_options = slides.BlobManagementOptions()
loadOptions.blob_management_options.presentation_locking_behavior = slides.PresentationLockingBehavior.KEEP_LOCKED
loadOptions.blob_management_options.is_temporary_files_allowed = True
loadOptions.blob_management_options.temp_files_root_path = "temp"

释放 Presentation 对象以释放内存

在处理大型演示文稿时,请确保正确处置 Presentation 实例,以释放其占用的内存。推荐的做法是使用上下文管理器(with slides.Presentation(...) as presentation:),如上例所示;块退出时它会自动关闭演示文稿并释放非托管资源。

如果在没有 with 块的情况下创建演示文稿,请在使用完成后显式调用 presentation.dispose(),并删除所有剩余引用,以便 Python 的垃圾回收器回收内存。

import aspose.slides as slides

presentation = slides.Presentation("large.pptx")
# ...处理演示文稿...
presentation.save("large.pdf", slides.export.SaveFormat.PDF)
# 明确释放资源。
presentation.dispose()

常见问题

Aspose.Slides 演示文稿中哪些数据被视为 BLOB 并受 BLOB 选项控制?

如图像、音频和视频等大型二进制对象会被视为 BLOB。当演示文稿加载或保存时,整个演示文稿文件也涉及 BLOB 处理。这些对象受 BLOB 策略管控,允许您在需要时管理内存使用并溢写到临时文件。

在加载演示文稿时,我在哪里配置 BLOB 处理规则?

使用 LoadOptions 搭配 BlobManagementOptions。在此可以设置 BLOB 的内存限制,是否允许临时文件,临时文件的根路径,以及源锁定行为。

BLOB 设置会影响性能吗?我该如何在速度与内存之间取得平衡?

是的。将 BLOB 保持在内存中可最大化速度,但会增加 RAM 消耗;降低内存限制会将更多工作转移到临时文件,从而降低 RAM 占用,但会产生额外的 I/O 开销。通过调节 max_blobs_bytes_in_memory 阈值,以在您的工作负载和环境中达到合适的平衡。

在打开极大型演示文稿(例如数 GB)时,BLOB 选项有帮助吗?

是的。BlobManagementOptions 专为此类场景设计:启用临时文件并使用源锁定可以显著降低峰值 RAM 使用,并在处理极大文稿时保持稳定。

我可以在从流而非磁盘文件加载时使用 BLOB 策略吗?

是的。同样的规则适用于流:演示文稿实例可以拥有并锁定输入流(取决于所选的锁定模式),并在允许的情况下使用临时文件,使处理期间的内存使用保持可预测。