0

I'm trying to save and load the states of Matrices (using Matrix) during the execution of my program with the functions dump and load from Marshal. I can serialize the matrix and get a ~275 KB file, but when I try to load it back as a string to deserialize it into an object, Ruby gives me only the beginning of it.

# when I want to save
mat_dump = Marshal.dump(@mat)  # serialize object - OK
File.open('mat_save', 'w') {|f| f.write(mat_dump)}  # write String to file - OK

# somewhere else in the code
mat_dump = File.read('mat_save')  # read String from file - only reads like 5%
@mat = Marshal.load(mat_dump)  # deserialize object - "ArgumentError: marshal data too short"

I tried to change the arguments for load but didn't find anything yet that doesn't cause an error.

How can I load the entire file into memory? If I could read the file chunk by chunk, then loop to store it in the String and then deserialize, it would work too. The file has basically one big line so I can't even say I'll read it line by line, the problem stays the same.

I saw some questions about the topic:

but none of them seem to have the answers I'm looking for.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
AdrienW
  • 3,092
  • 6
  • 29
  • 59
  • 1
    Can you read it in binary mode? Maybe the contains strange binary data that stops the file reading (EOF). See e.g. https://stackoverflow.com/questions/130948/ruby-convert-file-to-string – knut May 31 '17 at 18:34

1 Answers1

1

Marshal is a binary format, so you need to read and write in binary mode. The easiest way is to use IO.binread/write.

...
IO.binwrite('mat_save', mat_dump)
...
mat_dump = IO.binread('mat_save')
@mat = Marshal.load(mat_dump)

Remember that Marshaling is Ruby version dependent. It's only compatible under specific circumstances with other Ruby versions. So keep that in mind:

In normal use, marshaling can only load data written with the same major version number and an equal or lower minor version number.

Casper
  • 33,403
  • 4
  • 84
  • 79