【问题标题】:pickle.load - EOFError: Ran out of inputpickle.load - EOFError:输入不足
【发布时间】:2017-11-12 00:41:09
【问题描述】:

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

问题是当我尝试使用pickle 加载.obj 文件时,将代码从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 是一种开放语言,就像更复杂和受保护的语言一样,最有动力的人能够破解游戏或程序并检索相同的数据。

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

所以你可以理解,从我的角度来看,解码文件不需要受到有动力的人的保护。因为即使使用更复杂和受保护的语言,那个有动力的人也能得到他想要的。该保护用于对付不懂该语言的人。

【问题讨论】:

  • _load 函数中似乎有错误 - 您正在将未解码的图像数据与文件夹名称连接起来?此外,如果您需要有意义的帮助,您可以发布用于创建这些文件的代码,而不仅仅是描述它。实际上,您似乎有一些非常多余的步骤。
  • 顺便说一句,您报告的错误发生在我上面提到的部分之前,也会出错。问题似乎出在您的文件创建过程中。
  • 我添加了用于创建 .obj 文件的代码

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


【解决方案1】:

所以,如果你得到的错误确实是“pickle: run out of input”,那可能意味着你在上面的代码中弄乱了你的目录,并试图读取一个与你的 obj 同名的空文件文件是。

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

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

完全搞砸了。只需阅读它,您就会发现问题所在:您将文件名传递给main_uncode 方法,而没有目录信息。然后,如果它碰巧奏效了,就像我刚才在 cmets 中指出的那样,您将尝试使用未序列化的图像数据作为文件名来读取图像。 (您或其他人可能认为main_uncode 应该写入一个临时图像文件并将图像数据写入其中,以便 Pygame 可以读取它,但实际上它只是以字符串形式返回原始图像数据) .

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

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

第三件事:只需使用with 打开所有文件,而不仅仅是您使用图像库阅读的文件,花点时间学习更多有关 Python 的知识。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2013-03-21
    • 2012-05-11
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    相关资源
    最近更新 更多