Python: написание байтового потока для перезаписи существующего потока OLE структурированного хранилища Microsoft

Некоторые предыстории того, что я делаю:

Я пишу программу на Python 3 в надежде разработать процесс чтения и записи в типы файлов структурированного хранилища Microsoft OLE. Я могу создать простой графический интерфейс, который позволяет пользователю выбирать, какие хранилища и потоки они хотели бы читать и записывать, используя tkinter, PySimpleGUI. Я использую пакеты olefile, pandas и numpy для выполнения большинства моих программных работ, но я столкнулся с известной проблемой с olefile, которая:

Что размер записываемого байтового потока должен совпадать с размером существующего байтового потока в файле OLE. Это стало проблемой для меня относительно быстро после того, как я начал отлаживать свою программу.

Что мне нужно сделать?

После некоторых обширных исследований основных сайтов программирования и покупки книги, Python Programming на Win32 (особенно чтение Ch12 на COM-хранилище); Я впал в тупик.

https://github.com/joxeankoret/nightmare/blob/master/mutators/OleFileIO_PL.py

https://github.com/decalage2/olefile/issues/6

https://github.com/decalage2/olefile/issues/95

https://github.com/decalage2/olefile/issues/99

Ниже приведен разбавленный код, который я использую:

file_path = values[0]
xl_path = values[1]
data = olefile.OleFileIO(file_path)
storages = olefile.OleFileIO.listdir(data, streams=False, storages=True)
streams = olefile.OleFileIO.listdir(data, streams=True, storages=False)
stmdata = data.openstream(streams[index])
readData = data.openstream(streams[index]).read()
#Send the data into Excel to be manipulated by User
with pd.ExcelWriter(xl_path, engine='openpyxl') as ew:
   ew.book = xl.load_workbook(xl_path)
   df.to_excel(ew, sheet_name=tabNames)

Данные манипулируют, теперь прочитайте их обратно.

Используйте Pandas для чтения данных в DataFrame

df1 = pd.read_excel(xls, x, encoding='utf-8', header=None)
newDF = newDF[0].str.encode(encoding="utf-8")
byteString = newDF[0]

Следующий оператор допускает только одинаковый размер ByteStrings

data.write_stream(streams[setIndex], byteString)

ValueError: write_stream: данные должны быть того же размера, что и существующий поток

РЕДАКТИРОВАТЬ:

На этот вопрос ответила декальда в комментариях ниже. Вот код, который я использовал для решения своей проблемы:

istorage = pythoncom.StgOpenStorageEx(file_path, mode, STGFMT_STORAGE, 0, pythoncom.IID_IStorage)

istorage1 = istorage.OpenStorage(stgRelays, None, mode, None, 0)

istorage2 = istorage1.OpenStorage(storage_choice, None, mode, None, 0)

    for x in set_compArr:

        set_STM = x + '.TXT'

        istream = istorage2.OpenStream(set_STM, None, mode, 0)

        istream.Write(byteString)

1 ответ

Решение

Чтобы изменить файлы OLE/CFB, используйте pythoncom из расширений pywin32 в Windows (и, возможно, в Linux с WINE): https://github.com/mhammond/pywin32

Сначала откройте файл OLE, используя pythoncom.StgOpenStorageEx: http://timgolden.me.uk/pywin32-docs/pythoncom__StgOpenStorageEx_meth.html

Пример:

import pythoncom
from win32com.storagecon import *

mode = STGM_READWRITE|STGM_SHARE_EXCLUSIVE
istorage = pythoncom.StgOpenStorageEx(filename, mode, STGFMT_STORAGE, 0, pythoncom.IID_IStorage)

Затем используйте методы объекта PyIStorage: http://timgolden.me.uk/pywin32-docs/PyIStorage.html

OpenStream возвращает объект PyIStream: http://timgolden.me.uk/pywin32-docs/PyIStorage__OpenStream_meth.html

Вы можете использовать его методы для чтения, записи и изменения размера потока: http://timgolden.me.uk/pywin32-docs/PyIStream.html

Другие вопросы по тегам