user2107733
user2107733

Reputation:

How do I write to a file in Ruby?

There are many SO answers for this such as "How to write to file in Ruby?", but I am missing a point with a path to file:

I have a file structure like this:

├── test.txt
├── write_to_file.rb

and "write_to_file.rb" has the following content:

 File.open('test.txt', 'w') { |file| file.write('hello') }
 # tried ('./test.txt','w') ..as well.

How do I write some content to test.txt file from another write_to_file.rb?

Upvotes: 5

Views: 5456

Answers (2)

Stoic
Stoic

Reputation: 10754

The correct way:

file = File.join(File.dirname(__FILE__), 'test.txt')
File.open(file, 'w') { |f| f.puts 'hello' }

__FILE__ is the path to the file containing the above code, and since, your test.txt resides in the same directory as write_to_file.rb, this should work, regardless of which directory you are in, on your machine.

Also, note that, I have used puts method instead of write, since I prefer newlines. :)


Whats wrong with your Code (probably):

When you use test.txt, then the path is relative to the directory from where you are running your write_to_file.rb script. For example, if you run write_to_file.rb from your home directory, then test.txt will imply ~/test.txt.

Upvotes: 4

the Tin Man
the Tin Man

Reputation: 160601

The simple way to write content is:

content = 'stuff to write'
File.write('text.txt', content)

That will overwrite the file with the new content.

A more complicated way, which gives you a bit more control of the file content (whether it's text or binary) is to use:

File.open('text.txt', 'w') do |fo|
  fo.write(content)
end

Which accomplishes the same thing. The file-mode, w, tells Ruby to write. wb would tell Ruby to write binary content. The difference is in how line-ends are handled/translated during the write to the file. Ruby, like many other languages, is aware that Windows expects a different line-ending than *nix systems, and adjusts accordingly when writing text. Using the "binary" mode causes no line-end translation.

Inside the block, the fo variable is a file handle, so you can use it, along with write, print or puts to send the content to the file. They behave a little differently but, in general, for your purpose, will do the same thing.

Using a block with open tells Ruby to close the file after writing to it, when the block exits. Always open and close a file for as short a period of time as possible. Operating systems have a finite number of file handles available, and leaving them open can needlessly use them up so other apps can't use them.

You need to learn about how the operating system designates paths to resources/files.

'text.txt' is the same as './text.txt', which means it's in the current directory.

Using '../text.txt' means it's in the parent directory, and '..' means it's a relative path. Similarly 'subdir/text.txt' would mean that "text.txt" was in a subdirectory.

Using '/path/to/text.txt' means it's an absolute path, starting at the root of the disk, and you'd have to look in the 'path' directory, followed by its 'to' subdirectory, and would find "text.txt" there.

This is all covered in the IO class documentation. (And, before you ask, File inherits from IO, so everything available in IO is automatically in the File class.)

Upvotes: 2

Related Questions