ohana
ohana

Reputation: 6731

How to write to file in Ruby?

I need to read the data out of database and then save it in a text file.

How can I do that in Ruby? Is there any file management system in Ruby?

Upvotes: 671

Views: 733722

Answers (8)

dawg
dawg

Reputation: 103694

While this answer has many variants of opening a file and writing to it from a block there is no answer of how someone who came from C or Perl or Python might do it in a familiar way.

In the block variant, all the text written or read needs to be local to the block. The file is opened, written to, and closed in one block of code:

File.open('/tmp/test.txt', 'w'){|f| f << "Living the block life"}
           # closed automatically at the end
           # the file handle is no longer available 

In C, you would open a file this way:

FILE* fptr;
fptr = fopen("/tmp/test.txt", "w");
if (fptr == NULL) {
    printf(error_msg);
    exit(-1);
}
# continue with your file
# close when done. IMPORTANT because C can buffer and lose data if not closed
fclose(fptr)

In Perl, kinda similar:

open(FH, '>', '/tmp/test.txt') or die $!;
#         ^     this is write
# you need to close FH explicitly 

In Python, you can have both C style open / use / explicit close:

f = open("/tmp/test.txt", "w")
# can write to f but you need to close f explicitly 
f.close()

Python also has with blocks that are similar to Ruby's block open / explicit close:

with open("/tmp/test.txt", "w") as f:
    # do your writing
# when f goes out of scope, at the bottom file is automatically closed

If you want C style file open / explicit close in Ruby:

f=File.open('/tmp/test.txt', 'w') 
# If that cannot be opened, Ruby's default behavior is equivalent 
#    to Perl's open(FH, '>', '/tmp/test.txt') or die $!;
# File.open errors can be rescued also
# f needs to be explicitly closed like so:
f.close

Why would you want this? Suppose you have:

f=File.open('/tmp/test.txt', 'w') 
# rescue if used
# ...
# Things that don't fit in a block that need that file

f.puts(something)

# ...
f.close

Upvotes: 0

You can use the short version:

File.write('/path/to/file', 'Some glorious content')

It returns the length written; see ::write for more details and options.

To append to the file, if it already exists, use:

File.write('/path/to/file', 'Some glorious content', mode: 'a')

Upvotes: 770

Marko Tunjic
Marko Tunjic

Reputation: 1879

To destroy the previous contents of the file, then write a new string to the file:

open('myfile.txt', 'w') { |f| f << "some text or data structures..." } 

To append to a file without overwriting its old contents:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 

Upvotes: 29

jdl
jdl

Reputation: 17790

The Ruby File class will give you the ins and outs of ::new and ::open but its parent, the IO class, gets into the depth of #read and #write.

Upvotes: 194

Tombart
Tombart

Reputation: 32378

This is preferred approach in most cases:

 File.open(yourfile, 'w') { |file| file.write("your text") }

When a block is passed to File.open, the File object will be automatically closed when the block terminates.

If you don't pass a block to File.open, you have to make sure that file is correctly closed and the content was written to file.

begin
  file = File.open("/tmp/some_file", "w")
  file.write("your text") 
rescue IOError => e
  #some error occur, dir not writable etc.
ensure
  file.close unless file.nil?
end

You can find it in documentation:

static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance(argc, argv, klass);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, io, io_close, io);
    }
    return io;
}

Upvotes: 270

l3x
l3x

Reputation: 31226

For those of us that learn by example...

Write text to a file like this:

IO.write('/tmp/msg.txt', 'hi')

BONUS INFO ...

Read it back like this

IO.read('/tmp/msg.txt')

Frequently, I want to read a file into my clipboard ***

Clipboard.copy IO.read('/tmp/msg.txt')

And other times, I want to write what's in my clipboard to a file ***

IO.write('/tmp/msg.txt', Clipboard.paste)

*** Assumes you have the clipboard gem installed

See: https://rubygems.org/gems/clipboard

Upvotes: 38

mvndaai
mvndaai

Reputation: 3831

Zambri's answer found here is the best.

File.open("out.txt", '<OPTION>') {|f| f.write("write your stuff here") }

where your options for <OPTION> 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.

Upvotes: 119

Todd R
Todd R

Reputation: 18506

Are you looking for the following?

File.open(yourfile, 'w') { |file| file.write("your text") }

Upvotes: 993

Related Questions