我有一个从pickle文件导入数据的应用程序。它适用于Windows,但Mac和Linux的行为很奇怪。
在OS X中,除非我将文件类型设置为*。*,否则pickled文件(文件扩展名“.char”)不可用作选择。然后,如果我选择一个具有.char扩展名的文件,它将不会加载,从而产生错误
unpickle_file = cPickle.load(char_file)
ValueError:无法将字符串转换为float
但是,如果我创建一个没有.char扩展名的文件,该文件将加载正常。
在Linux中,当我使用“文件打开”对话框时,我的pickle文件是不可见的,无论它们是否具有文件扩展名。但是,我可以在Nautilus或Dolphin下看到它们。它们根本不存在于我的应用程序中。
修改以下是保存代码:
def createSaveFile(self):
"""Create the data files to be saved and save them.
Creates a tuple comprised of a dictionary of general character information
and the character's skills dictionary."""
if self.file_name:
self.save_data = ({'Name':self.charAttribs.name,
<snip>
self.charAttribs.char_skills_dict)
self.file = open(self.file_name, 'w')
cPickle.dump(self.save_data, self.file)
self.file.close()
这是开放代码:
def getCharFile(self, event): # wxGlade: CharSheet.<event_handler>
"""Retrieve pickled character file from disk."""
wildcard = "Character files (*.char) | *.char | All files (*.*) | *.*"
openDialog = wx.FileDialog(None, "Choose a character file", os.getcwd(),
"", wildcard, wx.OPEN | wx.CHANGE_DIR)
if openDialog.ShowModal() == wx.ID_OK:
self.path = openDialog.GetPath()
try:
char_file = open(self.path, "r")
unpickle_file = cPickle.load(char_file)
char_data, char_skills = unpickle_file
self.displayCharacter(char_data, char_skills)
except IOError:
self.importError = wx.MessageDialog(self,
"The character file is not available!",
"Character Import Error", wx.OK | wx.ICON_ERROR)
self.importError.ShowModal()
self.importError.Destroy()
openDialog.Destroy()
答案 0 :(得分:10)
在写入和/或读取pickle数据时,您可能没有以二进制模式打开文件。在这种情况下,将发生换行格式转换,这可能会破坏二进制数据。
要以二进制模式打开文件,您必须提供“b”作为模式字符串的一部分:
char_file = open('pickle.char', 'rb')
答案 1 :(得分:9)
如Adam所述,问题很可能是pickle文件的换行格式。
不幸的是,真正的问题实际上是由于 save 而不是加载造成的。如果您使用的是文本模式pickles而不是binary,那么这可能是可恢复的。尝试以通用换行模式打开文件,这将导致python猜测正确的行结尾是什么,即:
char_file=open('filename.char','rU')
但是,如果您使用的是二进制格式(cPickle.dump(file,1)),您可能会有一个不可恢复的损坏的pickle(即使在Windows中加载) - 如果您很幸运且没有\ r \ n字符显示然后它可能会工作,但是一旦发生这种情况你就可能最终得到损坏的数据,因为没有办法区分“真正的”\ r \ n代码和一个窗口插入只看\ n。。 p>
处理要在多个平台上加载的东西的最佳方法是始终以二进制模式保存。在您的Windows机器上,保存泡菜时使用:
char_file = open('filename.char','wb')
cPickle.dumps(data, char_file)
答案 2 :(得分:4)
获取此错误的另一种方法是忘记在酸洗后关闭输出文件。这可能会留下一个不完整的文件,在随后的拆除过程中会以随机的方式失败。
答案 3 :(得分:2)
self.file = open(self.file_name, 'w')
应该是:
self.file = open(self.file_name, 'wb')
在createSaveFile
功能中,以二进制模式(而不是文本模式)保存文件。您还应该确保以二进制模式打开文件(rb)。
如果你不使用二进制模式,那么Windows会将所有新行转换为\ r \ n,并且会有效地破坏文件(至少就其他操作系统而言)。
答案 4 :(得分:0)
使用dos2unix工具
dos2unix pickle.char