【问题标题】:How to put png file into a string and writing it to another file如何将png文件放入字符串并将其写入另一个文件
【发布时间】:2014-08-03 19:10:24
【问题描述】:

我正在尝试制作数据存档,但我的 data.gdf 不是应有的样子,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))

打印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...')

【问题讨论】:

  • 如果文件包含二进制数据,您需要按原样读取和写入它们(将 'b' 添加到 'r' 或 'w' 参数到 'open')。
  • 为什么不使用标准容器格式,例如shelvesqlite3 数据库来存储文件?
  • 加密@Roland Smith
  • @JudiSean 没有什么能阻止您将加密数据放在搁置或数据库中。但是,如果密钥存储在您的程序中,加密就几乎没用了。
  • 为什么没用,那我要在哪里存储密钥呢? @罗兰史密斯

标签: python image file python-2.7 file-io


【解决方案1】:

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())从文件末尾开始,什么都不返回(所以 len = 0)。试试吧:

dataLength = data.tell()

【讨论】:

    【解决方案2】:

    首先你必须设置二进制模式(“rb”或“wb”用于任何非文本文件)

    每次使用“r”或“w”(甚至是“rb”或“wb”)打开文件时,它都会重置为开头

    要获得文件的dataOffset,您可以调用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 的文件,就会发生奇怪的事情

    【讨论】:

    • 谢谢,刚刚对您的代码进行了小幅编辑以使其完美,因此请接受编辑@Xavier Combelle
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2013-04-09
    • 2015-12-29
    • 1970-01-01
    相关资源
    最近更新 更多