Python: написание байтового потока для перезаписи существующего потока OLE структурированного хранилища Microsoft - PullRequest
0 голосов
/ 05 марта 2019

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

Я пишу программу на 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

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

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: данные должны быть того же размера, что и существующий поток

EDIT:

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

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 Ответ

0 голосов
/ 06 марта 2019

Чтобы изменить файлы 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

...