简体   繁体   English

pickle.load - EOFError:输入输出

[英]pickle.load - EOFError: Ran out of input

I have an .obj file in which, previously, I transformed an image to base64 and saved with pickle . 我有一个.obj文件,之前我将图像转换为base64并用pickle保存。

The problem is when I try to load the .obj file with pickle , convert the code into image from base64, and load it with pygame . 问题是当我尝试使用pickle加载.obj文件时,将代码从base64转换为图像,并使用pygame加载它。

The function that loads the image: 加载图像的功能:

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()

The function that decodes the file: 解码文件的函数:

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

The error I get when the code is run: 运行代码时出现的错误:

str = pickle.load(openFile)

EOFError: Ran out of input EOFError:退出输入

How can I fix it? 我该如何解决?

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

Update 1 更新1

This is the code I used to create the .obj file: 这是我用来创建.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)

Once the file is created, it is loaded and a second image is created. 创建文件后,将加载该文件并创建第二个图像。 This is to check if the image is the same or there are errors in the conversion. 这是为了检查图像是否相同或转换中是否存在错误。

As you can see, I used part of the code to load the image, but instead of saving it, it is loaded into pygame . 如您所见,我使用部分代码加载图像,但不是保存它,而是加载到pygame And that's where the mistake occurs. 这就是错误发生的地方。

Update 2 更新2

I finally managed to solve it. 我终于设法解决了。

In the main code: 在主要代码中:

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")

In the library containing graphics classes: 在包含图形类的库中:

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()

For the question of why I should do such a thing, it is simple: 对于为什么我应该做这样的事情,这很简单:

any attacker with sufficient motivation can still get to it easily 任何有足够动力的攻击者仍然可以轻松搞定

Python is free and open. Python是免费和开放的。

On the one hand, we have a person who intentionally goes and modify and recover the hidden data. 一方面,我们有一个人故意去修改和恢复隐藏的数据。 But if Python is an open language, as with even more complicated and protected languages, the most motivated are able to crack the game or program and retrieve the same data. 但是,如果Python是一种开放式语言,就像更复杂和受保护的语言一样,最有动力的是能够破解游戏或程序并检索相同的数据。

On the other hand, we have a person who knows only the basics, or not even that. 另一方面,我们有一个人只知道基本知识,甚至不知道。 A person who cannot access the files without knowing more about the language, or decoding the files. 在不了解语言或解码文件的情况下无法访问文件的人。

So you can understand that decoding files, from my point of view, does not need to be protected from a motivated person. 因此,您可以理解,从我的角度来看,解码文件不需要受到保护,不需要受到激励。 Because even with a more complex and protected language, that motivated person will be able to get what he wants. 因为即使有更复杂和受保护的语言,这个有动力的人也能够得到他想要的东西。 The protection is used against people who have no knowledge of the language. 该保护用于对不懂语言的人。

So, if the error you get is indeed "pickle: run out of input", that propably means you messed your directories in the code above, and are trying to read an empty file with the same name as your obj file is. 所以,如果你得到的错误确实是“pickle:用完输入”,这可能意味着你在上面的代码中弄乱你的目录,并试图读取一个与你的obj文件同名的空文件。

Actually, as it is, this line in your code: 实际上,就像它一样,代码中的这一行:

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

Is completly messed up. 完全搞砸了。 Just read it and you can see the problem: you are passing to the main_uncode method just the file name, without directory information. 只需阅读它就可以看到问题所在:您只是将文件名传递给main_uncode方法,而没有目录信息。 And then, if it would by chance have worked, as I have poitned in the comments a while ago, you would try to use the unserialized image data as a filename from where to read your image. 然后,如果它偶然发挥作用,就像我刚才在评论中所说的那样,你会尝试使用未序列化的图像数据作为文件名,从哪里读取你的图像。 (You or someone else had probably thought that main_uncode should write a temporary image file and writ the image data to that, so that Pygame could read it, but as it is, it is just returning the raw image data in a string). (你或其他人可能认为main_uncode应该写一个临时的图像文件并将图像数据写入,以便Pygame可以读取它,但实际上,它只是将原始图像数据返回到一个字符串中)。

Threfore, by fixing the above call and passing an actual path to main_uncode , and further modifying it to write the temporary data to a file and return its path would fix the snippets of code above. 因此,通过修复上述调用并将实际路径传递给main_uncode ,并进一步修改它以将临时数据写入文件并返回其路径将修复上面的代码片段。

Second thing is I can't figure out why do you need this ".obj" file at all. 第二件事是我无法弄清楚为什么你需要这个“.obj”文件。 If it is just for "security through obscurity" hopping people get your bundled file can't open the images, that is a thing far from a recommended practice. 如果它只是为了“通过默默无闻的安全”跳跃的人得到你的捆绑文件无法打开图像,这是一个远非推荐的做法。 To sum up just one thing: it will delay legitimate uses of your file (like, you yourself does not seem to be able to use it ), while any attacker with sufficient motivation can still get to it easily. 总结一件事:它会延迟你的文件的合法使用(比如,你自己似乎无法使用它),而任何有足够动力的攻击者仍然可以轻松地使用它。 By opening an image, base-64 encoding and pickling it, and doing the reverse process you are doing essentially a no-operation. 通过打开图像,base-64编码并对其进行pickle,并执行相反的过程,您实际上是在进行无操作。 Even more, a pickle file can serialize and write to disk complex Python objects - but a base64 serialization of an image could be written directly to a file, with no need for pickle. 更重要的是,pickle文件可以序列化并写入磁盘复杂的Python对象 - 但是图像的base64序列化可以直接写入文件,而不需要pickle。

Third thing: just use with to open all the files, not just the ones you read with the imaging library, Take your time to learn a little bit more about Python. 第三件事:只要使用with打开所有你与成像库读取文件,不只是那些,把你的时间,以了解更多一点关于Python。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM