182
votes

I'm trying to create a new file and things don't seem to be working as I expect them too. Here's what I've tried:

File.new "out.txt"
File.open "out.txt"
File.new "out.txt","w"
File.open "out.txt","w"

According to everything I've read online all of those should work but every single one of them gives me this:

ERRNO::ENOENT: No such file or directory - out.txt

This happens from IRB as well as a Ruby script. What am I missing?

9
The first two should not work, but the second two are synonymous and definitely should work.Andrew Marshall
@Andrew: You're thinking that only the first two were tried?mu is too short
@muistooshort That's the only conclusion I can reach. A permissions error would have thrown Errno::EACCES, not ENOENT.Andrew Marshall
OK, now I feel stupid. The first two definitely do not work but the second two do. Not sure how I convinced my self that I had tried them. Sorry for wasting everyone's time.Civatrix
@Civatrix That's no problem. We all waste time sometimes.Darth Egregious

9 Answers

461
votes

Use:

File.open("out.txt", [your-option-string]) {|f| f.write("write your stuff here") }

where your options are:

  • r - Read only. The file must exist.
  • w - Create an empty file for writing.
  • a - Append to a file.The file is created if it does not exist.
  • r+ - Open a file for update both reading and writing. The file must exist.
  • w+ - Create an empty file for both reading and writing.
  • a+ - Open a file for reading and appending. The file is created if it does not exist.

In your case, 'w' is preferable.

OR you could have:

out_file = File.new("out.txt", "w")
#...
out_file.puts("write your stuff here")
#...
out_file.close
37
votes

Try

File.open("out.txt", "w") do |f|     
  f.write(data_you_want_to_write)   
end

without using the

File.new "out.txt"
28
votes

Try using "w+" as the write mode instead of just "w":

File.open("out.txt", "w+") { |file| file.write("boo!") }
21
votes

OK, now I feel stupid. The first two definitely do not work but the second two do. Not sure how I convinced my self that I had tried them. Sorry for wasting everyone's time.

In case this helps anyone else, this can occur when you are trying to make a new file in a directory that does not exist.

13
votes

If the objective is just to create a file, the most direct way I see is:

 FileUtils.touch "foobar.txt"
11
votes

The directory doesn't exist. Make sure it exists as open won't create those dirs for you.

I ran into this myself a while back.

11
votes

File.new and File.open default to read mode ('r') as a safety mechanism, to avoid possibly overwriting a file. We have to explicitly tell Ruby to use write mode ('w' is the most common way) if we're going to output to the file.

If the text to be output is a string, rather than write:

File.open('foo.txt', 'w') { |fo| fo.puts "bar" }

or worse:

fo = File.open('foo.txt', 'w')
fo.puts "bar"
fo.close

Use the more succinct write:

File.write('foo.txt', 'bar')

write has modes allowed so we can use 'w', 'a', 'r+' if necessary.

open with a block is useful if you have to compute the output in an iterative loop and want to leave the file open as you do so. write is useful if you are going to output the content in one blast then close the file.

See the documentation for more information.

2
votes
data = 'data you want inside the file'.

You can use File.write('name of file here', data)

0
votes

You can also use constants instead of strings to specify the mode you want. The benefit is if you make a typo in a constant name, your program will raise an runtime exception.

The constants are File::RDONLY or File::WRONLY or File::CREAT. You can also combine them if you like.

Full description of file open modes on ruby-doc.org