658

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?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
ohana
  • 6,601
  • 2
  • 17
  • 5

7 Answers7

985

Are you looking for the following?

File.open(yourfile, 'w') { |file| file.write("your text") }
Matthew Simoneau
  • 6,199
  • 6
  • 35
  • 46
Todd R
  • 18,236
  • 8
  • 31
  • 39
754

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')
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Sébastien Le Callonnec
  • 26,254
  • 8
  • 67
  • 80
269

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;
}
Tombart
  • 30,520
  • 16
  • 123
  • 136
  • Yes, using the block syntax with { |file| .... } will close the file when the block closes. – wesgarrison Feb 04 '13 at 20:38
  • Cool, thanks. I wasn't sure about that. Here's some more info about blocks and `File.open` http://blog.rubybestpractices.com/posts/rklemme/001-Using_blocks_for_Robustness.html it's also mentioned in the official documentation – Tombart Feb 05 '13 at 21:26
  • 1
    Just something ruby way-ish: nil is an object, so to check if a file is null, you ask the object itself instead of comparing (file.nil? instead of file == nil) – Yeray Cabello May 26 '15 at 11:13
  • @JCabello sure, that's definitely more Ruby-like approach, thanks! – Tombart May 26 '15 at 15:20
  • finally an answer that shows that one should also check for file status and how to handle it, and not just one liner that just shows the open call. – Nasser Jun 23 '15 at 01:33
  • Ruby way-ish: `!file` – Camille Goudeseune Aug 02 '16 at 01:27
195

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.

Michael Gaskill
  • 7,913
  • 10
  • 38
  • 43
jdl
  • 17,702
  • 4
  • 51
  • 54
  • 6
    Thanks @Geoff. It's good to see new users cleaning up outdated questions and answers. Makes for a better site overall. – jdl Oct 11 '12 at 16:43
  • 7
    I find this ironic. The answer is very well documented... but now a year later, this question is the first hit on Google. When the question was asked, it may have seemed that the OP was dedicating little effort but now as far as Google is concerned, this is the best source. – Jeff Dec 28 '13 at 16:28
  • 7
    Probably because everything you really need to know is here. Mine is the "teach a man to fish" answer for those who want to read the finer details, and there are plenty of "give a man a fish" answers here as well for people who just want to cut-and-paste. It's not surprising that this combination ends up well ranked on Google. – jdl Dec 31 '13 at 16:09
  • 1
    So, in fairness, I work in a lot of different languages, which means I rarely get around to remembering the syntax for any specific one. I've googled this a few times, and I always scroll right _past_ this answer, to the one below it, because when I google StackOverflow I'm usually just looking for a dang fish. :p Honestly tho it's good having both. Perhaps someday I will be doing enough Ruby all at once that I will care about the details. – user435779 Apr 08 '19 at 18:54
  • 4
    This does not answer the question. It merely points to the two classes that contain most of the methods for doing I/O, and makes no mention of the connection with the database. That would be fine as a comment, but hardly qualifies as an answer. I realise that the OP and the many readers who upvoted this answer disagree, and I frankly don't understand what they were thinking. – Cary Swoveland Jul 01 '19 at 16:54
  • I also upvoted this answer. The first thing that puzzled me when reading other answers was which one to use and when between File.write vs IO.write. This answer clarifies so much succintly. It show exactly where to look and what to look for. – sentifool Oct 29 '21 at 13:44
118

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.

Community
  • 1
  • 1
mvndaai
  • 3,453
  • 3
  • 30
  • 34
  • @CarySwoveland I actually agree with you. The real problem is that one of the two questions should have been marked as a duplicate a long time ago. I copied the answer because once I found the question zanbri had answered and the next few times when I needed the same info I came across this question first and had to figure out how to get to the other question. Eventually, I thought it would just be easier to have his answer here as well. I linked to his answer so hopefully, people would click over and give him an upvote as well. – mvndaai Jul 02 '19 at 00:38
38

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

l3x
  • 30,760
  • 1
  • 55
  • 36
  • 1
    Beware the `IO.write` option **overwrite** the file content instead of append. Append with IO.write is a bit tedious. – fguillen Nov 02 '16 at 13:22
  • Not sure what you're talking about? The IO.write command does not need that option to write to a file. I would be careful to either save the file to the /tmp directory or the current directory; Otherwise, you might see a `Errno::ENOENT: No such file or directory @ rb_sysopen` message and the file created with a size of 0 bytes. – l3x Jan 18 '17 at 02:04
28

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' } 
Marko Tunjic
  • 1,811
  • 1
  • 14
  • 15