Thursday, June 29, 2006

Reading from / Writing to Text files

Let's look at how we can read / write to a text file with the help of a simple program ReadWrite.rb.
# Open and read from a text file
File.open('Constructs.rb', 'r') do |f1|
while line = f1.gets
puts line
end
end

# Create a new file and write to it
File.open('Test.rb', 'w') do |f2|
# use "" for two lines of text
f2.puts "Created by Satish\nThank God!"
end
The File.open method can open the file in different modes like 'r' Read-only, starts at beginning of file (default); 'r+' Read/Write, starts at beginning of file; 'w' Write-only, truncates existing file to zero length or creates a new file for writing. Please check the online documentation for a full list of modes available. File.open opens a new File if there is no associated block. If the optional block is given, it will be passed file as an argument, and the file will automatically be closed when the block terminates.

Assignment: Write a Ruby program (call it SwapContents.rb) to do the following. Take two text files say A and B. The program should swap the contents of A and B ie. after the program is executed, A should contain B's contents and B should contains A's. Post your program as a comment to this post.

First Post | Previous | Next


Technorati Tags:
Blogs linking to this article

11 Comments:

Blogger Ashish Kulkarni said...

Approach 1 - a bit cheeky as it only renames the files :-)

File.rename("text1.txt", "text1.tmp")
File.rename("text2.txt", "text1.txt")
File.rename("text1.tmp", "text2.txt")

4:23 PM  
Blogger Ashish Kulkarni said...

Approach 2

# Swapfiles2.rb - Program to swap the contents of 2 text files
# Author - Ashish Kulkarni
# Date - 29-June-2006

# Function to read contents of one file and write them to another file
# Accepts 2 file names - file1 and file2
# Reads from file1 and writes to file2
def filereadwrite(file1, file2)
f2 = File.new(file2, "w")
f1 = File.open(file1, "r")
if f1 != nil then
while line = f1.gets
f2.puts line
end
f1.close
f2.close
return true
else
return false
end
end

filereadwrite("text1.txt", "text1.tmp")
filereadwrite("text2.txt", "text1.txt")
filereadwrite("text1.tmp", "text2.txt")

File.delete('text1.tmp')

6:44 PM  
Blogger Anil said...

A1 = File.open('A.txt','r').readlines
puts "Contents of files A.txt\n"
puts A1

A2 = File.open('B.txt','r').readlines
puts "Contents of file B.txt\n"
puts A2

File.open('A.txt','w') do |temp1|
temp1.puts A2
end

File.open('B.txt','w') do |temp2|
temp2.puts A1
end

b1 = File.open('A.txt','r').readlines
puts "Contents of file A.txt\n"
puts b1

b2 = File.open('B.txt','r').readlines
puts "Contents of file B.txt\n"
puts b2

Result
Contents of files A.txt
1234567
Contents of file B.txt
abcdefg
Contents of file A.txt
abcdefg
Contents of file B.txt
1234567

7:10 PM  
Blogger Gaurav V Bagga said...

f1 = (File.open('C:\2.txt','r')).readlines
File.open('c:\2.txt','w').write((File.open('C:\1.txt','r')).readlines)
File.open('c:\1.txt','w').write f1

11:48 PM  
Blogger eswar said...

This comment has been removed by a blog administrator.

8:59 AM  
Blogger eswar said...

def swapFiles( file1 , file2 )

f1 = File.open( file1 , "r")
f2 = File.open( file2 , "r" )

tmp = f1.readlines

f1.close

File.open( file1 , "w" ).write( f2.readlines )
File.open( file2 ,"w" ).write( tmp )

end

swapFiles( "test1.txt" , "test2.txt" )

9:01 AM  
Blogger eswar said...

sorry for the odd post.
No ++ in ruby ?? anything else missing ??
nd abt code blocks culd u pls explain how they internally work ??
culd we pass multiple arguments for code blocks ?? how ??
nd abt anish nd ashish's questions in the previous 2 posts ?

9:22 AM  
Blogger Unknown said...

Eswar there's no ++ operator in Ruby.

11:50 AM  
Blogger Aspirations said...

#Swap the contents of two files

file1 = File.open('File1.txt','r')
file2 = File.open('File2.txt','r')

var1 = file1.readlines
var2 = file2.readlines

tmp = var1
var1 = var2
var2 = tmp

file1.close
file2.close

File.open('File1.txt','w') do |file1|
file1.puts var1
end

File.open('File2.txt','w') do |file1|
file1.puts var2
end

4:25 PM  
Blogger शंतनू said...

require 'fileutils'
def copyfiles(src,dest)
begin
FileUtils.cp src,dest
rescue
return 1
end
end

f1='file1'
f2='file2'
ftmp='/tmp/filetmp'
if copyfiles(f1,ftmp)
print "Unable to create a backup of #{f1} to #{ftmp}\n"
exit
else
print "Backup of file #{f1} to #{ftmp} created\n"
end
if copyfiles(f2,f1)
print "Unable to copy #{f2} to #{f1}\n"
FileUtils.rm ftmp
exit
else
print "#{f2} copied to #{f1}\n"
end
if copyfiles(ftmp,f2)
print "Unable to copy #{ftmp} to #{f2}\n"
copyfiles(ftmp,f1)
FileUtils.rm ftmp
exit
else
print "#{ftmp} copied to #{f1}\n"
end

print "Successfuly swaped #{f1} and #{f2}\n"

12:33 AM  
Blogger Vasudev Ram said...

I liked Ashish's Approach 2, as it is more reusable code - the filereadwrite function can be used in other situations.

A comment on the solutions by all:
Some have copied the file contents to 1) an array, the others to 2) a temp file. I realize that this is only an exercise, not a real world app, but still - way 1) could fail if file is too large to fit in memory, while way 2) will be slower as compared to way 1) (since disk-to-disk I/O is going to be slower than disk-to-memory I/O).
One approach could be to check the file size, and if there is a Ruby API to check available memory, then if file size is less than free memory, use the way 1), else use way 2). Of course one would have to check for enough disk space for the temp file too. Just some comments from a real-world perspective ...

Vasudev
---
http://www.geocities.com/vasudevram

9:51 PM  

Post a Comment

<< Home