Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Why can't I create a new file?

Tags:

ruby

I'm trying to create a json file and write to it.

My code looks like this:

def save_as_json(object)
    f = File.new('file.json')
    f.puts(object.to_json, 'w')
    f.close
end

save_as_json({'name'=>'fred'})

The problem is, I get the following error when I run it:

:15:in `initialize': No such file or directory @ rb_sysopen - file.json (Errno::ENOENT)

I'm asking Ruby to create the file but it's complaining that it doesn't exist! What is the correct way to create and write to a file?

like image 906
user3574603 Avatar asked Jan 05 '23 23:01

user3574603


2 Answers

You just need to open the file using the 'w' mode like this:

f = File.new('file.json', 'w')

You want to determine the mode based on what you plan to do with the file, but here are your options:

"r" Read-only, starts at beginning of file (default mode).

"r+" Read-write, starts at beginning of file.

"w" Write-only, truncates existing file to zero length or creates a new file for writing.

"w+" Read-write, truncates existing file to zero length or creates a new file for reading and writing.

"a" Write-only, each write call appends data at end of file. Creates a new file for writing if file does not exist.

"a+" Read-write, each write call appends data at end of file. Creates a new file for reading and writing if file does not exist.

IO Docs

like image 74
Anthony Avatar answered Jan 16 '23 02:01

Anthony


File creation defaults to read mode, so trying to use a filespec that does not exist will result in an error:

2.3.0 :001 > f = File.new 'foo'
Errno::ENOENT: No such file or directory @ rb_sysopen - foo

You need to specify 'w':

2.3.0 :002 > f = File.new 'foo', 'w'
 => #<File:foo>

That said, there are easier ways to write to files than to get a file handle using File.new or File.open. The simplest way in Ruby is to call File.write:

File.write('file.json', object.to_json)

You can use the longer File.open approach if you want; if you do, the simplest approach is to pass a block to File.open:

File.open('file.json', 'w') { |f| f << object.to_json }

This eliminates the need for you to explicitly close the file; File.open, when passed a block, closes the file for you after the block has finished executing.

like image 29
Keith Bennett Avatar answered Jan 16 '23 02:01

Keith Bennett