How to write to file in Ruby?
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
.
How do I write to a file in Ruby?
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
.
Write to a file in Ruby with every iteration of a loop
Let's use IO::write to create two input files.
FNameIn1 = 'in1'
File.write(FNameIn1, "cow\npig\ngoat\nhen\n")
#=> 17
We can use IO::read to confirm what was written.
puts File.read(FNameIn1)
cow
pig
goat
hen
FNameIn2 = 'in2'
File.write(FNameIn2, "12\n34\n56\n78\n")
#=> 12
puts File.read(FNameIn2)
12
34
56
78
Next, use File::open to open the two input files for reading, obtaining a file handle for each.
f1 = File.open(FNameIn1)
#=> #<File:in1>
f2 = File.open(FNameIn2)
#=> #<File:in2>
Now open a file for writing.
FNameOut = 'out'
f = File.open(FNameOut, "w")
#=> #<File:out>
Assuming the two input files have the same number of lines, in a while
loop read the next line from each, combine the two lines in some ways and the write the resulting line to the output file.
until f1.eof
line11 = f1.gets.chomp
line12 = f1.gets.chomp
line21 = f2.gets.chomp
line22 = f2.gets.chomp
f.puts "%s %s, %s %s" % [line11, line21, line12, line22]
end
See IO#eof, IO#gets and IO#puts.
Lastly, use IO#close to close the files.
f1.close
f2.close
f.close
Let's see that FileOut
looks like.
puts File.read(FNameOut)
cow 12, pig 34
goat 56, hen 78
We can have Ruby close the files by using a block for each File::open
:
File.open(FNameIn1) do |f1|
File.open(FNameIn2) do |f2|
File.open(FNameOut, "w") do |f|
until f1.eof
line11 = f1.gets.chomp
line12 = f1.gets.chomp
line21 = f2.gets.chomp
line22 = f2.gets.chomp
f.puts "%s %s, %s %s" % [line11, line21, line12, line22]
end
end
end
end
puts File.read FNameOut
cow 12, pig 34
goat 56, hen 78
This is in fact how it's normally done in Ruby, in part to avoid the possibility of forgetting to close files.
Here's another way, using IO::foreach, which, without a block, returns an enumerator, allowing the use of Enumerable#each_slice, as referenced in the question.
e1 = File.foreach(FNameIn1).each_slice(2)
#=> #<Enumerator: #<Enumerator: File:foreach("in1")>:each_slice(2)>
e2 = File.foreach(FNameIn2).each_slice(2)
#=> #<Enumerator: #<Enumerator: File:foreach("in2")>:each_slice(2)>
File.open(FNameOut, "w") do |f|
loop do
line11, line12 = e1.next.map(&:chomp)
line21, line22 = e2.next.map(&:chomp)
f.puts "%s %s, %s %s" % [line11, line21, line12, line22]
end
end
puts File.read(FNameOut)
cow 12, pig 34
goat 56, hen 78
We may observe the values generated by the enumerator
e1 = File.foreach(FNameIn1).each_slice(2)
by repeatedly executing Enumerator#next:
e1.next
#=> ["cow\n", "pig\n"]
e1.next
#=> ["goat\n", "hen\n"]
e1.next
#=> StopIteration (iteration reached an end)
The StopIteration
exception, when raised, is handled by Kernel#loop by breaking out of the loop (which is one reason why loop
is so useful).
Confusion about creating and writing to File in Ruby on rails
If you don't end along the filename as an option for send_data, it defaults to the method name.
Secondly, the download wants to read the data from a buffer. My guess is your syntax is just sending a file handle.
Try this...
send_data(file.read, filename: filename)
Or skip the intermediate file and try...
send_data(version_to_download.liquid_code.to_s, filename: filename)
ruby How to read a file and write to another file while skipping lines
File.open("output.txt", "w") do |file_to_write|
File.open("input.txt").each do |line|
if $. % 4 == 2
file_to_write.write(line.chomp)
end
if $. % 4 == 3
file_to_write.write(line)
end
end
end
Ruby has a special symbol which will give you the line number $.
you can substitute that with File.open(filename).each_with_index do |line, index|
and use index instead of $.
.
If you use an index you will need to add 1 to it, because it will start off at 0.
This code goes through your input file line-by-line. The lines starting from the second and third line and then each following line of interest is offset by 4.
Once we find the first half write that line to our opened file without a new line, once we find the second half (second if
statement) write that line with a line terminator to the file.
How to write a file in specific path in ruby
Your code has multiple errors. Have you ever tried to execute the script?
Your script ends with:
test.rb:7: unknown regexp options - fldr
test.rb:7: syntax error, unexpected end-of-input
F = open.(Dir.pwd, /data/folder /#{@file_name },w+)
First: You need to define the strings with '
or "
:
file_name = gets
F = open.(Dir.pwd, "/data/folder/#{@file_name}","w+")
Some other errors:
- You use
file_name
and later@file_name
. - The
open
method belongs toFile
and needs two parameters. - The file is defined as a constant
F
. I would use a variable. - The path must be concatenated. I'd use
File.join
for it. - You don't close the file.
After all these changes you get:
file_name = gets
f = File.open(File.join(Dir.pwd, "/data/folder/#{file_name}"),"w+")
##
f.close
and the error:
test.rb:29:in `initialize': No such file or directory @ rb_sysopen - C:/Temp/data/folder/sdssd (Errno::ENOENT)
The folder must exist, so you must create it first.
Now the script looks like:
require 'fileutils'
dirname = "data/folder"
file_name = gets.strip
FileUtils.mkdir_p(dirname) unless Dir.exists?(dirname)
f = File.open(File.join(Dir.pwd, dirname, file_name),"w+")
##fill the content
f.close
How to write variables in a file?
You can call write
:
userId = 76
userkey = "UtRzoP"
configFile = File.new("file.txt", "w")
configFile.write("id=#{userId}\nkey=#{userkey}")
configFile.close
As others in the comments point out, you can do the same with blocks:
File.open("file.txt", "w") { |f| f.write("id=#{userId}\nkey=#{userkey}") }
PS: puts
puts a new line at the end of the string when written to a file. Personally, I favor write
because it doesn't put that last new line in the end.
How to create a file in Ruby
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
How to write a file with ruby?
I think you would do better using Ruby's TempFile class and perhaps even Ruby's temp dir as suggested in this article: Quick tips for doing IO with Ruby.
I think you will find the article helpful. I believe it will make your approach easier - especially regarding deleting the file once you're done with it.
How do I save the text of puts in Ruby to a txt file?
There are ways to save the output of a script to a file without having to modify every puts
in the script.
The easiest is to route the output at the command-line using redirection. Running a script with > some_file
at the of the command will route all STDOUT to the file. Similarly, using > some_file 2>&1
will route both STDOUT and STDERR to the same file. This won't capture anything typed in at a gets
as the code waits for input though, because that won't count as program output.
If you don't mind changing your code a little, you can temporarily change the interpreter's idea of what STDOUT is by reassigning it to a file:
old_stdout = $stdout
File.open('output.txt', 'w') do |fo|
$stdout = fo
# ----
# your code goes here
puts "hello world"
# ----
end
$stdout = old_stdout
Run that, then look at the file "output.txt" and you'll see "hello world", even though we didn't print to the file-handle fo
directly, like we would normally do using fo.puts
.
There are a variety of ways of doing the same thing but they amount to pointing STDOUT or STDERR somewhere else, writing to them, then resetting them.
Typically, if we intend from the start to output to a file, then we should use a File.open
block:
File.open('output.txt', 'w') do |fo|
fo.puts "hello world"
end
The benefit of that is the file will be closed automatically when the block exits.
Related Topics
How to Check If a Value Exists in an Array in Ruby
Ssl Error When Installing Rubygems, Unable to Pull Data from 'Https://Rubygems.Org/
Combining Implicit Wait and Explicit Wait Together Results in Unexpected Wait Times
What's the Difference Between Uri.Escape and Cgi.Escape
Rails Keeps Telling Me That It's Not Currently Installed
Nokogiri Installation Fails -Libxml2 Is Missing
Accepts_Nested_Attributes_For With Belongs_To Polymorphic
How to Set Default Values in Rails
To_D to Always Return 2 Decimals Places in Ruby
Difference Between "And" and && in Ruby
Code Block Passed to Each Works With Brackets But Not With 'Do'-'End' (Ruby)
How to Avoid Running Activerecord Callbacks
What Exactly Is the Singleton Class in Ruby