python-3.x - 如何关闭在 Python/pythoncom/comtypes 中打开的 Windows 便携式设备 IStream
问题描述
我在 python 中使用带有 pythoncom 和 comtypes 的 Windows 便携式设备。
我遇到了麻烦,因为当我请求 WPD_RESOURCE_THUMBNAIL 资源时,一些 android 设备返回一个“方形”缩略图,而原始图像具有 16:9 格式(或 4:3 ...)。
然后我尝试请求 WPD_RESOURCE_DEFAULT 资源以从 EXIF 数据中获取缩略图:因此无需读取整个文件,一旦获得缩略图的 EXIF 标签,我可以停止读取并跳到下一个文件。
我可以从 EXIF 中获取第一个文件的缩略图。在第二个文件上,我卡在 GetStream() 方法上。它只是挂起。我想是因为上一次调用的 IStream 没有关闭/处理。
您对如何强制此 IStream 的 Dispose / Close 有任何想法吗?
这就是我在代码中所做的:
optimalTransferSizeBytes, fileStream = resources.GetStream(
self.objectID,
WPD_RESOURCE_DEFAULT,
ctypes.c_ulong(0),
optimalTransferSizeBytes,
pFileStream
)
提前感谢您对此的任何建议。
编辑:由于我没有找到其他方法来中断流并释放所有资源,因此我最终读取了 WPD_RESOURCE_DEFAULT 的整个流。它有点慢,但更安全,因为应用程序也在大屏幕上运行,并且使用 EXIF 的缩略图会导致屏幕上的图像质量很差。因此,我决定为此目的读取 WPD_RESOURCE_DEFAULT 的整个流,并在这一点之外的某个地方加速代码。感谢@ShadowRanger 的支持。
解决方案
该UnmanagedMemoryStream
类型有一个Dispose
方法,如果您的库为您公开了所有方法,那么简单的fileStream.Dispose()
应该可以工作。为了安全起见,您可能希望实现一个上下文管理器包装器以允许使用该with
语句,或者使用较少的 Python 语言,但更简单的是,使用try
/ finally
,例如:
optimalTransferSizeBytes, fileStream = resources.GetStream(
self.objectID,
WPD_RESOURCE_DEFAULT,
ctypes.c_ulong(0),
optimalTransferSizeBytes,
pFileStream
)
try:
... do stuff with fileStream ...
finally:
fileStream.Dispose()
或者,您可以制作自己的上下文管理器来执行处置:
from contextlib import contextmanager
@contextmanager
def disposing(disposable):
try:
yield disposable
finally:
disposable.Dispose()
这将允许稍微更好的代码:
optimalTransferSizeBytes, fileStream = resources.GetStream(
self.objectID,
WPD_RESOURCE_DEFAULT,
ctypes.c_ulong(0),
optimalTransferSizeBytes,
pFileStream
)
with disposing(fileStream):
... do stuff with fileStream ...
推荐阅读
- reactjs - 反应组件冲突
- sql - 从质心、宽度和距离创建边界框的最佳方法?
- python - zipfile.ZipFile 提取错误的文件
- sql - 提高 SQL 查询性能。UNION vs OR 在这种情况下
- python - 无法使用 .setItem(row, colum, QTableWidgetItem(data)) 填充 QTableWidget
- java - 对多个 xml 文件进行高性能编组
- python-3.x - ModuleNotFoundError:没有名为“sparknlp”的模块
- image - Colab代码在jupyter笔记本中不起作用
- c - 当运行一个无限循环时,为什么 int 或 char 在最后给出负值
- flutter - 安装后 Flutter 尝试安装