pickle.load - EOFError:输入输出

时间:2017-11-12 00:41:09

标签: python python-3.x pygame base64 pickle

我有一个.obj文件,之前我将图像转换为base64并保存为pickle

问题是当我尝试使用.obj加载pickle文件时,将代码从base64转换为图像,然后使用pygame加载。

加载图片的功能:

def mainDisplay_load(self):
    main_folder = path.dirname(__file__)
    img_main_folder = path.join(main_folder, "sd_graphics")

    # loadImg
    self.mainTerminal = pg.image.load(path.join(img_main_folder, self.main_uncode("tr.obj"))).convert_alpha()

解码文件的函数:

def main_uncode(self, object):
    openFile = open(object, "rb")
    str = pickle.load(openFile)
    openFile.close()
    fileData = base64.b64decode(str)
    return fileData

运行代码时出现的错误:

str = pickle.load(openFile)
  

EOFError:退出输入

我该如何解决?

  • Python版本:3.6.2
  • Pygame版本:1.9.3

更新1

这是我用来创建.obj文件的代码:

import base64, pickle

with open("terminal.png", "rb") as imageFile:
    str = base64.b64encode(imageFile.read())
    print(str)

file_pi = open("tr.obj","wb")
pickle.dump(str,file_pi)
file_pi.close()

file_pi2 = open("tr.obj","rb")
str2 = pickle.load(file_pi2)
file_pi2.close()

imgdata = base64.b64decode(str2)
filename = 'some_image.jpg'  # I assume you have a way of picking unique filenames
with open(filename, 'wb') as f:
    f.write(imgdata)

创建文件后,将加载该文件并创建第二个图像。这是为了检查图像是否相同或转换中是否存在错误。

正如您所看到的,我使用了部分代码来加载图像,但不是保存它,而是加载到pygame。那就是错误发生的地方。

更新2

我终于设法解决了。

在主要代码中:

def mainDisplay_load(self):
    self.all_graphics = pg.sprite.Group()
    self.graphics_menu = pg.sprite.Group()

    # loadImg
    self.img_mainTerminal = mainGraphics(self, 0, 0, "sd_graphics/tr.obj")

在包含图形类的库中:

import pygame as pg
import base64 as bs
import pickle as pk
from io import BytesIO as by
from lib.setting import *

class mainGraphics(pg.sprite.Sprite):
    def __init__(self, game, x, y, object):
        self.groups = game.all_graphics, game.graphics_menu
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.object = object
        self.outputGraphics = by()

        self.x = x
        self.y = y

        self.eventType()

        self.rect = self.image.get_rect()
        self.rect.x = self.x * tilesizeDefault
        self.rect.y = self.y * tilesizeDefault

    def eventType(self):
        openFile = open(self.object, "rb")
        str = pk.load(openFile)
        openFile.close()
        self.outputGraphics.write(bs.b64decode(str))
        self.outputGraphics.seek(0)
        self.image = pg.image.load(self.outputGraphics).convert_alpha()

关于为什么我应该做这样的事情,这很简单:

  

任何有足够动力的攻击者仍然可以轻松搞定

Python是免费且开放的。

一方面,我们有一个人故意去修改和恢复隐藏数据。但是,如果Python是一种开放式语言,就像更复杂和受保护的语言一样,最有动力的是能够破解游戏或程序并检索相同的数据。

另一方面,我们有一个人只知道基本知识,甚至不知道。无法在不了解语言或解码文件的情况下无法访问文件的人。

因此,您可以理解,从我的角度来看,解码文件不需要受到保护,不需要受到激励。因为即使有更复杂和受保护的语言,这个有动力的人也能够得到他想要的东西。该保护措施用于对不懂语言的人。

1 个答案:

答案 0 :(得分:1)

所以,如果你得到的错误确实是“pickle:用完输入”,这可能意味着你在上面的代码中弄乱了你的目录,并试图读取一个与你的{{1}同名的空文件文件是。

实际上,实际上,代码中的这一行:

obj

完全搞砸了。只需阅读它就可以看到问题所在:您只是将文件名传递给self.mainTerminal=pg.image.load(path.join(img_main_folder,self.main_uncode ("tr.obj"))).convert_alpha() 方法,而没有目录信息。然后,如果它偶然发挥作用,就像我刚才在评论中所说的那样,你会尝试使用未序列化的图像数据作为文件名,从哪里读取你的图像。 (你或其他人可能认为main_uncode应该编写一个临时图像文件并将图像数据写入其中,以便Pygame可以读取它,但实际上,它只是将原始图像数据返回到字符串)。

因此,通过修复上述调用并将实际路径传递给main_uncode,并进一步修改它以将临时数据写入文件并返回其路径将修复上面的代码片段。

第二件事是我无法弄清楚为什么你需要这个“.obj”文件。如果它只是为了“通过默默无闻的安全”跳跃的人得到你的捆绑文件无法打开图像,这是一个远非推荐的做法。总结一件事:它会延迟你的文件的合法使用(比如,你自己似乎无法使用它),而任何有足够动力的攻击者仍然可以轻松地使用它。通过打开图像,base-64编码并对其进行pickle,并执行相反的过程,您实际上是在进行无操作。更重要的是,pickle文件可以序列化并写入磁盘复杂的Python对象 - 但是图像的base64序列化可以直接写入文件,而不需要pickle。

第三件事:只需使用main_uncode打开所有文件,而不仅仅是使用成像库读取的文件,花些时间学习更多关于Python的知识。