gpt4 book ai didi

ruby - 为什么在 Ruby 中使用 Marshal 转储和加载哈希会抛出 FormatError?

转载 作者:数据小太阳 更新时间:2023-10-29 06:43:06 25 4
gpt4 key购买 nike

我正在运行从 RubyInstaller 安装的 Ruby .这是版本:

C:\Users\Sathya>ruby -v
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

这是抛出错误的确切代码:

hashtime = Hash.new(Time.mktime('1970'))
hashtime[1] = Time.now
=> 2011-10-04 19:26:53 +0530
print hashtime
{1=>2011-10-04 19:26:53 +0530}=> nil
hashtime[1] = Time.now
=> 2011-10-04 19:27:20 +0530
print hashtime
{1=>2011-10-04 19:27:20 +0530}=> nil
File.open('timehash','w') do |f|
f.write Marshal.dump(hashtime)
end
=> 56

现在,尝试加载它。

Marshal.load (File.read('timehash'))

给出错误:

ArgumentError: dump format error for symbol(0x42)
from (irb):10:in `load'
from (irb):10
from C:/Ruby192/bin/irb:12:in `<main>'

为什么会抛出错误?我做错了什么,或者这是一个错误?

我运行的是 Windows 7 Ultimate,64 位


这是您提到的已编辑调试代码的结果:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 20:49:52 +0530
hashdump = Marshal.dump(hashtime)
=> "\x04\b{\x06i\x06Iu:\tTime\r\x8F\xE4\e\x80<\xADGO\x06:\voffseti\x02XM"
hashtime = Marshal.load (hashdump)
=> {1=>2011-10-04 20:49:52 +0530}
print hashtime
{1=>2011-10-04 20:49:52 +0530}=> nil

要编辑的结果 2:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:04:24 +0530
hashdump = Marshal.dump(hashtime)
=> "\x04\b{\x06i\x06Iu:\tTime\r\x8F\xE4\e\x80\x92o\x8C\x89\x06:\voffseti\x02XM"
print "hashdump: #{hashdump}"
ÅS?ÇÆoîë?:?offseti?XM=> nile
File.open('timehash','w') do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read('timehash')
=> "\x04\b{\x06i\x06Iu:\tTime\n\x8F\xE4\e\x80\x92o\x8C\x89\x06:\voffseti\x02XM"
print "hashdump2: #{hashdump2}"
hashdump2:{?i?Iu: Time
ÅS?ÇÆoîë?:?offseti?XM=> nil
hashtime2 = Marshal.load (hashdump2)
ArgumentError: dump format error for symbol(0x8c)
from (irb):73:in `load'
from (irb):73
from C:/Ruby192/bin/irb:12:in `<main>'

部分人物没出来,截图如下:

hash-dump-marshal


现在我得到一个时间格式不同的错误

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:23:15 +0530
hashdump = Marshal.dump(hashtime)
=> "\x04\b{\x06i\x06Iu:\tTime\r\x8F\xE4\e\x80\xB9\xE1\xFB\xD4\x06:\voffseti\x02X
M"
print "hashdump: #{hashdump}"
ÅΣ←Ç╣ß√╘♠:♂offseti☻XM=> nile
File.open('timehash','wb') do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read('timehash')
=> "\x04\b{\x06i\x06Iu:\tTime\n\x8F\xE4\e\x80\xB9\xE1\xFB\xD4\x06:\voffseti\x02X
M"
print "hashdump2: #{hashdump2}"
hashdump2:{♠i♠Iu: Time
ÅΣ←Ç╣ß√╘♠:♂offseti☻XM=> nil
hashtime2 = Marshal.load (hashdump2)
TypeError: marshaled time format differ
from (irb):10:in `_load'
from (irb):10:in `load'
from (irb):10
from C:/Ruby192/bin/irb:12:in `<main>'

最佳答案

您需要通过将 b 附加到文件模式以二进制模式写入文件:

File.open('timehash','wb') do |f|
f.write Marshal.dump(hashtime)
end

通过比较写入磁盘之前和读回之后的字符串(来 self 们的调试),您可以看出问题所在:

=> "\x04\b{\x06i\x06Iu:\tTime\r\x8F\xE4\e\x80\x92o\x8C\x89\x06:\voffseti\x02XM"
=> "\x04\b{\x06i\x06Iu:\tTime\n\x8F\xE4\e\x80\x92o\x8C\x89\x06:\voffseti\x02XM"
^^

a \r(回车)正在更改为 \n(换行)

但是,即使使用二进制修饰符,您的系统似乎也没有服从您,而是将 \r 更改为 \n...所以让我们尝试对数据进行编码到 base64:

File.open('timehash','w') do |f|
hashtime_marshal = Marshal.dump(hashtime)
f.write [hashtime_marshal].pack("m")
end

hashtime_encoded = File.read('timehash')
hashtime = Marshal.load( hashtime_encoded.unpack("m")[0] )

让我知道这是否有效?


旧信息:

不要将任何内容传递给 Hash.new:

>> hashtime = Hash.new
=> {}
>> hashtime[1] = Time.now
=> Tue Oct 04 10:57:49 -0400 2011
>> hashtime
=> {1=>Tue Oct 04 10:57:49 -0400 2011}
>> File.open('timehash','w') do |f|
?> f.write Marshal.dump(hashtime)
>> end
=> 22
>> Marshal.load (File.read('timehash'))
(irb):10: warning: don't put space before argument parentheses
=> {1=>Tue Oct 04 10:57:49 -0400 2011}

文档指出 Hash.newobj 参数是默认值...它应该像您拥有的那样工作。 .. 我不知道为什么它不......但在你的情况下 nil 是一个可接受的默认值,只需检查值是否为 nil 如果是,请为它们使用 Time.mktime('1970')

编辑: 这为我解决了问题,但是,我使用的是 OS X 而不是 Windows。所以,让我们尝试一些调试。当您运行以下代码时会发生什么?

hashtime = Hash.new
hashtime[1] = Time.now
hashdump = Marshal.dump(hashtime)
hashtime = Marshal.load (hashdump)
print hashtime

编辑 #2: 好的。所以 Marshal.dumpMarshal.load 似乎有效。看起来它与文件 I/O 有关...请发布以下代码的结果...

hashtime = Hash.new
hashtime[1] = Time.now
hashdump = Marshal.dump(hashtime)
print "hashdump: #{hashdump}"
File.open('timehash','w') do |f|
f.write hashdump
end
hashdump2 = File.read('timehash')
print "hashdump2: #{hashdump2}"
hashtime2 = Marshal.load (hashdump2)
print hashtime2

关于ruby - 为什么在 Ruby 中使用 Marshal 转储和加载哈希会抛出 FormatError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7649175/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com