Mixing IO#read and IO#syswrite

The docs clearly warn against mixing buffered and unbuffered reads, or
mixing buffered and unbuffered writes. But is it ok to open a file, read
its contents, truncate it, and syswrite new contents? It seems to work
fine, but …

The reason I’m asking is that I want a file with marshalled data to be
consistent (as in the ACID properties) regardless of failures. I’m
guessing a dump to a string followed by a syswrite is the best way to do
this, because the single OS call won’t be interrupted by ruby, and so if
the file system has the consistency property (I guess a journaled fs
would suffice), the marshalled data will be consistent.

But I want to avoid allocating strings, if possible. So I use

Marshal.load(file)

to get the objects without allocating an extra string, then

file.rewind
file.truncate(0)
file.syswrite(Marshal.dump(obj))

to write out the new contents.

I could just use an intermediate string to load the data:

Marshal.load(file.sysread(…))

But I’d like to avoid the extra allocation, if possible.

Is my approach safe?

Hi,

···

At Sun, 2 Mar 2003 06:51:38 +0900, Joel VanderWerf wrote:

file.rewind
file.truncate(0)
file.syswrite(Marshal.dump(obj))

It’s safe because IO#rewind and underlying IO#seek implies
IO#flush.


Nobu Nakada