如何将png文件转为字符串并写入另一个文件
我正在尝试制作一个数据归档,但我的数据文件 data.gdf 的格式不太对。这个文件是把所有文件连接在一起的,所有内容一个接一个地存储,没有任何分隔符。数据文件 data.gdh 中记录的起始偏移量和长度非常重要,如果其中任何一个不正确,损坏的记录所描述的文件就无法提取,显然后面的文件也很可能无法提取。目前我在尝试创建一个包含 png 文件的数据归档,但似乎不太成功。
import os
#--------Encryption/Decryption of data---------#
hidden
#--------Encryption/Decryption of data---------#
# #
#--------------------Main----------------------#
with open('Output//data.gdf', 'w') as gdf: # clean data.gdf
gdf.write('')
files = []
for (path, dirnames, filenames) in os.walk('Data'):
files.extend(os.path.join(path, name) for name in filenames)
file_data = 'YwuiHg'
for i in files:
with open(i, 'r') as data:
with open('Output//data.gdf', 'r') as gdf:
dataOffset = len(gdf.read())
with open('Output//data.gdf', 'w') as gdf:
gdf.write(data.read())
dataLength = len(data.read())
file_data += i + str(dataOffset) + 'FR' + str(dataLength) + 'FT' + 'eihwfw'
print file_data
with open('Output//data.gdh', 'w') as gdh:
gdh.write(encrypt(key, file_data))
当我打印文件数据时:
YwuiHgData\images\background.png0FR1749FTeihwfwData\images\background1.png5FR354FTeihwfwData\images\gameover.png5FR0FTeihwfwData\images\ground.png5FR1571FTeihwfwData\images\icon.png5FR599FTeihwfwData\images\loadbackground.png5FR314FTeihwfwData\images\medal1.png5FR0FTeihwfwData\images\medal2.png5FR0FTeihwfwData\images\medal3.png5FR0FTeihwfwData\images\medal4.png5FR0FTeihwfwData\images\player1.png5FR0FTeihwfwData\images\player2.png5FR0FTeihwfwData\images\player3.png5FR0FTeihwfwData\images\playerdead.png5FR0FTeihwfwData\images\scorereward.png5FR0FTeihwfwData\images\start.png5FR239FTeihwfw
偏移量和数据长度似乎也搞乱了。我该如何解决这些问题呢?非常感谢!
编辑:这个问题已经被 @XavierCombelle 解决了,但我在加载图像时遇到了新问题,比如列表中的第一个图像 background.png
。当我输入它的完整路径 Data\images\background.png
时,它找不到这个路径,但如果我只输入 background.png
就可以找到。这是不是和 \
是转义字符有关?我自己解决了:
try:
os.remove('Output//data.gdf')
except:
'file does not exist, no need to delete'
files = []
for (path, dirnames, filenames) in os.walk('Data'):
files.extend(os.path.join(path, name) for name in filenames)
file_data = 'YwuiHg'
#ab mode writes to the end of the file so need to have clean file when beginning to make new data.gdf otherwise the whole file would be messed up.
print 'Opening data.gdf for writing...\n'
with open('Output//data.gdf', 'ab') as gdf:
for i in files:
i.replace("\ ","\\")
with open(i, 'rb') as data_file:
data = data_file.read()
dataOffset = str(gdf.tell())
dataLength = str(len(data))
print 'Writing to data.gdf ' + i + ' at offset ' + dataOffset + '. Data Length ' + dataLength
gdf.write(data)
print 'Storing identity of data into file_data -> ' + i + dataOffset + 'FR' + dataLength + 'FT' + 'eihwfw\n'
file_data += i + dataOffset + 'FR' + dataLength + 'FT' + 'eihwfw'
print 'Encrypting file_data variable and writing it to data.gdh'
with open('Output//data.gdh', 'w') as gdh:
gdh.write(encrypt(key, file_data))
exiting = raw_input('Press any key to continue...')
2 个回答
open('Output//data.gdf', 'w')
这个命令会清空输出文件,也就是说你之前写入的数据会丢失。所以每次写入时,你的偏移量总是从上一个写入的内容开始(文件里其他的内容每次都会被清掉)。
你可以把对输出文件的两个 open()
调用简化成一个,并且改成追加模式:
with open('Output//data.gdf', 'a') as gdf:
dataOffset = gdf.tell()
gdf.write(data.read())
数据长度出错是因为第一次 data.read()
会一直读取到数据文件的末尾,这样 len(data.read())
就从文件末尾开始,什么都不返回(所以长度为0)。可以试试这样:
dataLength = data.tell()
首先,你需要把文件设置为二进制模式(对于非文本文件,使用“rb”或“wb”)。
每次你用“r”或“w”打开一个文件(即使是“rb”或“wb”),文件的读取位置都会重置到开头。
如果你想知道文件的当前位置,可以使用tell()这个方法。
当你使用data.read()读取文件时,它会把整个文件内容都读完,这样之后再读取就会返回一个长度为0的空字符串。
所以,核心循环可以用下面的方式替换:
#wb mode reset data.gdf so no need to doing previous write
with open('Output//data.gdf', 'wb') as gdf:
for i in files:
with open(i, 'rb') as data_file:
data = data_file.read()
dataOffset = gdf.tell()
gdf.write(data)
dataLength = len(data)
file_data += i + str(dataOffset) + 'FR' + str(dataLength) + 'FT' + 'eihwfw'
gdf文件格式看起来很奇怪,比如如果你有一个名为127FR49FTeihwfw.png的文件,就会发生一些奇怪的事情。