5

I have an array of UInt32, what is the most efficient way to write it into a binary file in Crystal lang?

By now I am using IO#write_byte(byte : UInt8) method, but I believe there should be a way to write bigger chunks, than per 1 byte.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
Sergey Potapov
  • 3,819
  • 3
  • 27
  • 46
  • How are you writing UInt32 with UInt8? Do you mean you are using write_bytes (with an s at the end)? – asterite Feb 07 '16 at 00:33
  • Currently I am keeping array of UInt8 and writing UInt8. But I guess it will be better to keep array of UInt32 and use it for writing as well – Sergey Potapov Feb 08 '16 at 21:28

1 Answers1

6

You can directly write a Slice(UInt8) to any IO, which should be faster than iterating each item and writing each bytes one by one.

The trick is to access the Array(UInt32)'s internal buffer as a Pointer(UInt8) then make it a Slice(UInt8), which can be achieved with some unsafe code:

array = [1_u32, 2_u32, 3_u32, 4_u32]

File.open("out.bin", "w") do |f|
  ptr = (array.to_unsafe as UInt8*)
  f.write ptr.to_slice(array.size * sizeof(UInt32))
end

Be sure to never keep a reference to ptr, see Array#to_unsafe for details.

Julien Portalier
  • 2,959
  • 1
  • 20
  • 22