[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to append some data at the beginning of a file

Uday Thokala

8/24/2007 10:42:00 AM

Hi,

I am newbie to Ruby so please spare me if the question looks silly. My
question is how to append data at the beginning of a file?

Suppose I have a file named test.rb which contains some text, say
"This is first line
This is second line"

Now if I wanted to append some data at the beginning of the file, lets
say
"This line has to be appended at the beginning of the file"

My program

filename = File.open("test","a") do |f|
f.puts "This line should appear at the top of each file";
f.close();
end

is appending at the end of the file. So the output is:

"This is first line
This is second line
This line has to be appended at the beginning of the file"

I searched the forums and found that if I use IO:seek and then try to
append data to the existing file the earlier content which are in the
first lines will get replaced. Is there any easy solution so that I can
get a final output like:

"This line has to be appended at the beginning of the file
This is first line
This is second line"
--
Posted via http://www.ruby-....

8 Answers

Ronald Fischer

8/24/2007 11:01:00 AM

0

> I am newbie to Ruby so please spare me if the question looks silly. My
> question is how to append data at the beginning of a file?

This is not so much a Ruby question, since nearly no operating system
directly
allows appending data to the beginning of a file. The general solution
is to create a new file, putting there the data in the right order,
delete
the old file and rename the new file to the name of the old one.

Renaming a file is done like this:

File.rename("oldname","newname")

This raises the exception SystemCallError, if renaming fails.

HTH

Ronald
--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

Uday Thokala

8/24/2007 11:28:00 AM

0

Ronald Fischer wrote:
>> I am newbie to Ruby so please spare me if the question looks silly. My
>> question is how to append data at the beginning of a file?
>
> This is not so much a Ruby question, since nearly no operating system
> directly
> allows appending data to the beginning of a file.

Thanks Ronald for your comments. I am wondering may be ruby got some way
around it.

> The general solution
> is to create a new file, putting there the data in the right order,
> delete
> the old file and rename the new file to the name of the old one.
>
> Renaming a file is done like this:
>
> File.rename("oldname","newname")

Yeah I implemented the above mentioned solution and it's working fine.
The code is

newfile = File.new("test1","w")
newfile.puts "This line should appear at the top of each file";

oldfile = File.open("test", "r+")
oldfile.each_line { |line| newfile.puts line}

oldfile.close();
newfile.close();

File.delete("test");
File.rename("test1", "test");

Thanks,
Uday.
--
Posted via http://www.ruby-....

Ronald Fischer

8/24/2007 11:40:00 AM

0

> Thanks Ronald for your comments. I am wondering may be ruby
> got some way
> around it.

It could, but I think it just happens too rare that someone
wants to do this. In more than 2 decades of programming, I
had this need only two or three times, for example.

> newfile = File.new("test1","w")
> newfile.puts "This line should appear at the top of each file";
>
> oldfile = File.open("test", "r+")
> oldfile.each_line { |line| newfile.puts line}
> oldfile.close();

or simply

newfile.puts(File.read("test"))

so you don't need the Ruby variable 'oldfile'.

> newfile.close();
>
> File.delete("test");
> File.rename("test1", "test");


--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

Jano Svitok

8/24/2007 11:55:00 AM

0

On 8/24/07, Ronald Fischer <ronald.fischer@venyon.com> wrote:
> > Thanks Ronald for your comments. I am wondering may be ruby
> > got some way
> > around it.
>
> It could, but I think it just happens too rare that someone
> wants to do this. In more than 2 decades of programming, I
> had this need only two or three times, for example.
>
> > newfile = File.new("test1","w")
> > newfile.puts "This line should appear at the top of each file";
> >
> > oldfile = File.open("test", "r+")
> > oldfile.each_line { |line| newfile.puts line}
> > oldfile.close();
>
> or simply
>
> newfile.puts(File.read("test"))
>
> so you don't need the Ruby variable 'oldfile'.
>
> > newfile.close();
> >
> > File.delete("test");
> > File.rename("test1", "test");

1. it's better to use block form of File.open:

File.open("test1","w") do |newfile|
newfile.puts "This line should appear at the top of each file"

File.open("test", "r+") do |oldfile|
oldfile.each_line { |line| newfile.puts line}
end
end

File.delete("test");
File.rename("test1", "test");

The difference is that in case of an exception the file is closed
automatically. Otherwise you have to wait for garbage collector. It's
a good habit to get used to this style.

2. newfile.puts(File.read("test")) will read the entire file into
memory. Don't do this on large files - use the original way (or even
better, loop over the file with File#read(size)). For small files,
this read() is better.

3. newfile.puts(File.read("test")) will put an extra newline at the
end. Use either
newfile << File.read("test")
or
newfile.write(File.read("test"))

Robert Klemme

8/24/2007 12:02:00 PM

0

2007/8/24, Uday Thokala <udaykanth_t@yahoo.co.in>:
> Ronald Fischer wrote:
> >> I am newbie to Ruby so please spare me if the question looks silly. My
> >> question is how to append data at the beginning of a file?
> >
> > This is not so much a Ruby question, since nearly no operating system
> > directly
> > allows appending data to the beginning of a file.
>
> Thanks Ronald for your comments. I am wondering may be ruby got some way
> around it.
>
> > The general solution
> > is to create a new file, putting there the data in the right order,
> > delete
> > the old file and rename the new file to the name of the old one.
> >
> > Renaming a file is done like this:
> >
> > File.rename("oldname","newname")
>
> Yeah I implemented the above mentioned solution and it's working fine.
> The code is
>
> newfile = File.new("test1","w")
> newfile.puts "This line should appear at the top of each file";
>
> oldfile = File.open("test", "r+")
> oldfile.each_line { |line| newfile.puts line}
>
> oldfile.close();
> newfile.close();
>
> File.delete("test");
> File.rename("test1", "test");

Just a few remarks: better return to your old habit and use the block
form of File.open (btw, you do not need to close the file, File#open
takes care of that when the block is left - even in case of an
exception).

You don't need to terminate lines with ";".

Also, you can use variables to make your life easier:

file = "test"
tmp = file + "~"

File.open(tmp, "w") do |out|
out.puts "This line should appear at the top of each file"

File.foreach file do |line|
out.puts line
end
end

File.delete file
File.rename tmp, file

Kind regards

robert

Ronald Fischer

8/24/2007 12:16:00 PM

0

> 2. newfile.puts(File.read("test")) will read the entire file into
> memory. Don't do this on large files - use the original way (or even
> better, loop over the file with File#read(size)). For small files,
> this read() is better.

Good point! (Only that *prepending* data to a file which is so big that
it would be a memory hog, is probably a nightmare anyway.

> 3. newfile.puts(File.read("test")) will put an extra newline at the
> end. Use either
> newfile << File.read("test")
> or
> newfile.write(File.read("test"))

Right, I overlooked this! Thanks for pointing this out.

Ronald

Florian Aßmann

8/24/2007 12:54:00 PM

0

My solution for this question would be monkey patching the File class:

require 'tempfile'

class File
def self.prepend(path, string)
Tempfile.open File.basename(path) do |tempfile|
# shift string to tempfile
tempfile << string

File.open(path, 'r+') do |file|
# append original data to tempfile
tempfile << file.read
# reset file positions
file.pos = tempfile.pos = 0
# copy tempfile back to original file
file << tempfile.read
end
end
end
end

Regards
Florian

Tom Reilly

8/27/2007 1:58:00 AM

0

Here is a small example to write something at the beginning of a file
which works fine so long as the length of this item doesn't change.

#-----------------------------------------------
#timer to track time I work on medicine
#version 1.3 8/12/07
# sleep added
# total time computed and displayed

rw = "r+"
$stdout.sync = true
begin
fo = File.new("time_study.txt",rw)
rescue
rw = "w+"
retry
end
old_chapter = fo.read(3)
if old_chapter == nil
fo.write("00\t *** \t \n")
p "Start a new file"
else
puts old_chapter
end



fo.seek(0,IO::SEEK_SET)
time_start = Time.now

prev_chapter = fo.read(2)
puts "Start at chapter #{prev_chapter}"
puts "Enter chapter to start"
fo.seek(0,IO::SEEK_SET)
chapter = gets.chomp
fo.write("#{chapter}")
time_end = Time.now
fo.seek(0,IO::SEEK_END)
fo.write("#{time_start.to_i} #{time_end.to_i} #{(time_end -
time_start)}\n")
fo.seek(0,IO::SEEK_SET)
total_time = 0.0
fo.each do |x|
xa = x.split
total_time += xa[2].to_f
end
puts "Total time Hours = #{total_time / 3600.0}"
sleep 10
fo.close