Python:编写字节流以覆盖现有的Microsoft结构化存储OLE流

时间:2019-03-05 17:18:17

标签: python-3.x com ole structured-storage

我正在做的事情的背景:

我正在用Python 3编写程序,希望开发一个可以读写Microsoft OLE结构化存储文件类型的过程。 我能够创建一个简单的GUI,允许用户选择使用tkinter PySimpleGUI读取和写入的存储和流。 我正在使用olefile,pandas和numpy程序包执行大部分程序,但是我遇到了olefile的已知问题,即:

正在写入的字节流的大小必须与OLE文件中现有的字节流的大小相同。在开始调试程序后,这相对较快地成为了我的问题。

我该怎么办?

经过对主要编程站点的广泛研究并购买了《 Win32上的Python编程》(特别是阅读COM存储器上的Ch12)一书;我陷入了困境。

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)

数据已被处理,现在将其读回。

使用熊猫将数据读取到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:数据大小必须与现有流相同

编辑:

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 :(得分:0)

一种修改OLE / CFB文件的方法是在Windows(可能是带有WINE的Linux)上使用pywin32扩展中的pythoncom:https://github.com/mhammond/pywin32

首先,使用pythoncom.StgOpenStorageEx打开OLE文件: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