如何关闭Python/pythoncom/comtypes中打开的Windows Portable Device IStream
解决WPD操作中IStream未释放导致GetStream()挂起的问题
我在使用Python的pythoncom和comtypes库操作Windows Portable Device(WPD)时遇到了一个头疼的问题:
- 一开始请求
WPD_RESOURCE_THUMBNAIL资源时,部分安卓设备返回的是方形缩略图,但原图片是16:9或4:3的比例,完全不符合我的需求。 - 于是我换了个思路,打算请求
WPD_RESOURCE_DEFAULT资源,从图片的EXIF数据里提取缩略图——这样不用读取完整文件,只要拿到EXIF缩略图标签就能停止读取,直接处理下一个文件。 - 第一次操作很顺利,成功拿到了缩略图,但处理第二个文件时,调用
GetStream()方法直接挂起了。我猜这肯定是前一次调用的IStream没被正确关闭或释放,导致资源被占住了。
相关代码片段:
optimalTransferSizeBytes, fileStream = resources.GetStream( self.objectID, WPD_RESOURCE_DEFAULT, ctypes.c_ulong(0), optimalTransferSizeBytes, pFileStream )
可能的解决方案
针对COM对象的IStream释放问题,你可以试试这几种方法:
显式调用
Release()方法:
COM对象靠引用计数管理生命周期,每次引用计数加1,调用Release()就减1。当计数降到0时,系统会自动释放资源。处理完流之后,手动调用:fileStream.Release()这是最直接的释放方式,能确保前一个
IStream的引用计数被正确减少。使用
pythoncom.ReleaseComObject():
如果你用的是pythoncom库,还可以调用pythoncom.ReleaseComObject(fileStream)强制释放COM对象。不过要注意,要是还有其他地方引用这个对象,这么做可能会引发错误,一定要确认完全用完后再调用。提交流操作后再释放:
对于IStream接口,要是有写入操作,先调用fileStream.Commit(STGC_DEFAULT)提交所有未完成的操作,再调用Release()。就算是只读流,这么做也能确保流的状态被正确清理,减少资源残留的可能。
我的最终处理方式
不过我试了好几种方法,都没找到完美的中断流并释放资源的途径,最后索性改成直接读取完整的WPD_RESOURCE_DEFAULT流。虽然速度慢了一点,但胜在安全,而且还解决了EXIF缩略图在大屏设备上画质差的问题。
内容的提问来源于stack exchange,提问作者shakraw
相关产品推荐
相关产品推荐

