Python: 编写字节流以覆盖现有的 Microsoft 结构化存储 OLE 流
Python: Writing a bytestream to overwrite an existing Microsoft Structured Storage OLE Stream
我正在做的一些背景:
我正在Python 3 中编写一个程序,希望开发一个进程来读取和写入Microsoft OLE 结构化存储文件类型。
我能够创建一个简单的 GUI,允许用户使用 tkinter PySimpleGUI 选择他们想要读取和写入的存储和流。
我正在使用 olefile、pandas 和 numpy 包来执行我的大部分程序跑腿工作,但我遇到了 olefile 的一个已知问题,即:
正在写入的字节流的大小必须与 OLE 文件中现有字节流的大小相同。在我开始调试我的程序后,这对我来说很快就成了一个问题。
我需要做什么?
在对主要编程站点进行广泛研究并购买本书后,Python 在 Win32 上编程(特别是阅读 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)
数据被操纵,现在读回。
使用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:数据必须与现有流的大小相同
编辑:
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)
一种修改 OLE/CFB 文件的方法是使用 Windows 上的 pywin32 扩展中的 pythoncom(也许 Linux 使用 WINE):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
returns 一个 PyIStream 对象:http://timgolden.me.uk/pywin32-docs/PyIStorage__OpenStream_meth.html
您可以使用它的方法来读取、写入和更改流的大小:http://timgolden.me.uk/pywin32-docs/PyIStream.html
我正在做的一些背景:
我正在Python 3 中编写一个程序,希望开发一个进程来读取和写入Microsoft OLE 结构化存储文件类型。 我能够创建一个简单的 GUI,允许用户使用 tkinter PySimpleGUI 选择他们想要读取和写入的存储和流。 我正在使用 olefile、pandas 和 numpy 包来执行我的大部分程序跑腿工作,但我遇到了 olefile 的一个已知问题,即:
正在写入的字节流的大小必须与 OLE 文件中现有字节流的大小相同。在我开始调试我的程序后,这对我来说很快就成了一个问题。
我需要做什么?
在对主要编程站点进行广泛研究并购买本书后,Python 在 Win32 上编程(特别是阅读 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)
数据被操纵,现在读回。
使用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:数据必须与现有流的大小相同
编辑:
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)
一种修改 OLE/CFB 文件的方法是使用 Windows 上的 pywin32 扩展中的 pythoncom(也许 Linux 使用 WINE):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
returns 一个 PyIStream 对象:http://timgolden.me.uk/pywin32-docs/PyIStorage__OpenStream_meth.html
您可以使用它的方法来读取、写入和更改流的大小:http://timgolden.me.uk/pywin32-docs/PyIStream.html