Child process accessing a file opened in Crystal

When I run the following code, the output is empty:

f = File.new("test.txt", "w")
f << "Hello world"
puts `cat test.txt`

However, if I add a rewind or close

f = File.new("test.txt", "w")
f << "Hello world"
f.rewind # or f.close
puts `cat test.txt`

It does print “Hello world”.

I don’t understand how the file descriptor from the Crystal code can affect a completely separate cat command that simply gets the file name as its argument. I assume it’s related to the fact that the created process is a child of the running crystal process, but I’m not sure exactly how.

File is buffered by default. If you don’t close the file the contents won’t be there. An alternative is to invoke f.flush or set f.sync = true which won’t make writes buffered anymore.

3 Likes