/ / Dlaczego wyładowywanie i ładowanie skrótu za pomocą marszałka w Ruby powoduje formatError? - rubin, dyrekcja

Dlaczego zrzucanie i ładowanie skrótu za pomocą marszałka w Ruby powoduje błąd FormatError? - rubin, dyrekcja

Mam zainstalowany system Ruby RubyInstaller. Oto wersja:

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

Oto dokładny kod, który rzuca błąd:

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

Teraz próbuję go załadować.

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

Daje błąd:

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

Dlaczego to powoduje błąd? Czy robię coś złego, czy jest to błąd?

Używam Windows 7 Ultimate, 64-bit


Oto wyniki edytowanego kodu debugowania, o którym wspomniałeś:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 20:49:52 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80<xADGOx06:voffsetix02XM"
hashtime = Marshal.load (hashdump)
=> {1=>2011-10-04 20:49:52 +0530}
print hashtime
{1=>2011-10-04 20:49:52 +0530}=> nil

Wyniki do edycji 2:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:04:24 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
print "hashdump: #{hashdump}"
ÅS?ÇÆoîë?:?offseti?XM=> nile
File.open("timehash","w") do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read("timehash")
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
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>"

Niektóre postacie nie wyszły, oto zrzut ekranu:

hash-dump-marshal


Teraz otrzymuję inny format formatu czasu

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:23:15 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80xB9xE1xFBxD4x06:voffsetix02X
M"
print "hashdump: #{hashdump}"
ÅΣ←Ç╣ß√╘♠:♂offseti☻XM=> nile
File.open("timehash","wb") do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read("timehash")
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80xB9xE1xFBxD4x06:voffsetix02X
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>"

Odpowiedzi:

5 dla odpowiedzi № 1

Połączenie 2 odpowiedzi z @Josh i @derp działa dla mnie. Oto kod (zapisany do pliku):

hashtime = Hash.new(Time.mktime("1970"))
hashtime[1]  = Time.now
File.open("timehash","wb") do |f|
f.write Marshal.dump(hashtime)
end
newhash = Marshal.load (File.binread("timehash"))
p newhash
p newhash.default

Wyniki w następującym wyniku:

c:appsruby>ruby h.rb
{1=>2011-10-05 08:09:43 +0200}
1970-01-01 00:00:00 +0100

12 dla odpowiedzi nr 2

Musisz napisać do pliku w trybie binarnym, dodając a b do trybu pliku:

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

Możesz zobaczyć, że to jest problem, porównując ciągi znaków (z naszego debugowania) przed zapisaniem na dysku i po ponownym przeczytaniu:

=> "x04b{x06ix06Iu:tTimerx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
^^

za r (powrót karetki) zmienia się na a n (Nowa linia)

Jednak wydaje się, że nawet przy binarnym modyfikatorze twój system nie przestrzega cię i się zmienia r do n... Spróbujmy zakodować dane na 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] )

Daj mi znać, czy działa?


Stare informacje:

Nic nie przekazuj 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}

Dokumentacja stwierdza, że obj parametr do Hash.new jest wartością domyślną ... to powinien pracuj tak, jak masz ... Nie wiem, dlaczego tak nie jest ... ale w twoim przypadku nil jest akceptowalnym domyślnym, po prostu sprawdź, czy są wartości nil a jeśli tak, użyj a Time.mktime("1970") dla nich zamiast tego.

EDYTOWAĆ: To rozwiązało problem dla mnie, jednak jestem na OS X nie Windows, więc spróbujmy trochę debugowania. Co stanie się, gdy uruchomisz poniższy kod?

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

EDYCJA # 2: DOBRZE. Więc Marshal.dump i Marshal.load wydaje się działać. Wygląda na to, że jest to coś z plikiem I / O ... Proszę opublikować wyniki następującego kodu ...

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

7 dla odpowiedzi nr 3

Zamiast czytać z File.read próbować File.binread lub File.open("timehash", "rb")