Как закрыть Windows Portable Device IStream, открытый в Python / pythoncom / comtypes - PullRequest
0 голосов
/ 30 мая 2018

Я использую переносное устройство Windows в python с pythoncom и comtypes.

У меня проблемы, потому что, когда я запрашиваю ресурс WPD_RESOURCE_THUMBNAIL, некоторые устройства Android возвращают "квадратный" эскиз, в то время как исходное изображение имеетФормат 16: 9 (или 4: 3 ...).

Затем я попытался запросить ресурс WPD_RESOURCE_DEFAULT, чтобы получить миниатюру из данных EXIF: поэтому нет необходимости читать весь файл, как только яполучить тег EXIF ​​для миниатюры. Я могу остановить чтение и перейти к следующему файлу.

Я могу получить миниатюру из EXIF ​​для самого первого файла.Во втором файле я застреваю в методе GetStream ().Это просто повесить.Я полагаю, потому что IStream из предыдущего вызова не был закрыт / удален.

Есть ли у вас какие-либо идеи о том, как принудительно утилизировать / закрыть этот IStream?

Это то, что я делаю в коде:

optimalTransferSizeBytes, fileStream = resources.GetStream(
                    self.objectID,
                    WPD_RESOURCE_DEFAULT,
                    ctypes.c_ulong(0),
                    optimalTransferSizeBytes,
                    pFileStream
                )

Заранее благодарю за любые предложения по этому вопросу.

РЕДАКТИРОВАТЬ : Поскольку я не нашел других способов прервать поток и освободить все ресурсы,В итоге я прочитал весь поток для WPD_RESOURCE_DEFAULT.Это немного медленнее, но безопаснее, потому что приложение работает и на больших экранах, а использование эскиза EXIF ​​может привести к ухудшению качества изображения на экране.Поэтому я решил прочитать весь поток для WPD_RESOURCE_DEFAULT для этой цели и ускорить код где-то за пределами этой точки.Спасибо @ShadowRanger за поддержку.

1 Ответ

0 голосов
/ 30 мая 2018

Тип UnmanagedMemoryStream имеет метод Dispose , если ваша библиотека предоставляет вам все методы, простой fileStream.Dispose() должен работать.Чтобы быть в безопасности, вы должны либо реализовать оболочку диспетчера контекста, чтобы разрешить использование оператора with, либо менее Pythonically, но проще - использовать 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 ...
...