206

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?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Civatrix
  • 2,566
  • 4
  • 17
  • 16

9 Answers9

482

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
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
zanbri
  • 5,958
  • 2
  • 31
  • 41
  • 12
    great answer. Ruby conevntion is snake case for var names. Just a heads up for newbies. `outFile` should look like `out_file`. – Adam Waite Aug 08 '13 at 10:46
  • 3
    @AdamWaite I edited the answer as per your snake_case suggestion, leaving this comment for context. – Kris Aug 08 '13 at 12:20
  • 6
    @zanbri - what happens if I don't close the file ? – Erran Morad Sep 27 '14 at 07:18
  • @Kris Will the same work for creating '.docx' files too? Because I am able to generate the file but I have a problem in opening them. – Sri Harsha Kappala Feb 13 '15 at 10:07
  • Should do. The issue might be cahracter encoding or is docx a binary format. – Kris Feb 13 '15 at 11:01
  • Do you guys think that it's ok to write `File.new("out.txt", "w").close` if one just wants to create a new file without putting content in it at creation time? Will the file be correctly closed after creation with this syntax? – Redoman Aug 07 '15 at 05:51
  • @jj_ I think that will work. You could also do `File.open("out.txt", "w") {}` as described here: http://stackoverflow.com/a/8100754/3345375 – jkdev Nov 19 '15 at 06:29
  • 2
    @BoratSagdiyev "A File object which is no longer referenced becomes eligible for garbage collection. The file will be closed automatically when the File object is garbage collected." http://www.rootr.net/rubyfaq-9.html – jkdev Nov 19 '15 at 06:45
  • How can I make a multi-line file like I have to make a list of students and their ages. Like column and rows. Can this work? – Uttam Manher Aug 16 '18 at 05:07
  • Great answer with excellent explanation of each mode. I'll just add that the shortened method for this is: `File.write( "out.txt", "write_your_stuff_here" )`. This will truncate an existing file or create a new file if one doesn't exist, write the contents to it and close the file. – Joshua Pinter Dec 08 '18 at 13:39
  • 3
    @jkdev, yes, it will be closed, but it's still considered code smell to rely on that, just as if the programmer never closed files and let the OS close the files when the interpreter terminates. And both can lead to a bad bug if multiple files are opened and the code never closes them leading to an out-of-handles condition and error. It's just a better, safer, practice to deliberately close them or rely on a block that does so automatically. – the Tin Man Dec 06 '19 at 19:31
41

Try

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

without using the

File.new "out.txt"
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
GMD
  • 698
  • 5
  • 12
32

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

File.open("out.txt", "w+") { |file| file.write("boo!") }
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Chris Bunch
  • 87,773
  • 37
  • 126
  • 127
21

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.

tom
  • 2,335
  • 1
  • 16
  • 30
16

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

 FileUtils.touch "foobar.txt"
Nicola Mingotti
  • 860
  • 6
  • 15
13

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
11

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Nicholas Terry
  • 1,812
  • 24
  • 40
3
data = 'data you want inside the file'.

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

ispirett
  • 648
  • 10
  • 10
0

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