comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Write to a certain line of a file
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Write to a certain line of a file [message #78956] Thu, 19 January 2012 11:02 Go to next message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
Michael Galloy writes:

> You are essentially treating the file as a binary file where you have
> more options, but also more responsibility for keeping things straight.
>
> Sure, this would work in the case where the new output has the exact
> same length in bytes as the old output, but if not everything is going
> to get screwed up. You could rewrite the file after the point of
> insertion to fix this, but how much is it worth it to get around writing
> this file?

I was curious how long it would take to re-write a 10000 line ASCII file
after replacing a line in it. Answer: 0.014 seconds!

Here is the code I used.

;----------------------------------------------------------- ----
; Create a random set of strings.
LENGTH=10000
len = Round(Scale_Vector(Randomu(-3L, LENGTH), 10, 60))
file = StrArr(LENGTH)
FOR j=0,N_Elements(len)-1 DO BEGIN
str = Byte(Scale_Vector(RandomU(seed, len[j]), 97, 122))
space = Fix(randomu(seed, len[j]/5 > 1) * len[j] > 2)
str[space] = 32B
file[j] = String(str)
ENDFOR

; Write the random strings to a file.
OpenW, lun, 'test_ascii_file.txt', /Get_Lun
FOR j=0, LENGTH-1 DO PrintF, lun, file[j]
Free_Lun, lun

; Replace line 50 with 'The dog ate my homework!'
start = Systime(1)
lines = File_Lines('test_ascii_file.txt')
OpenR, lun, 'test_ascii_file.txt', /Get_Lun
strings = StrArr(lines)
strings[49] = 'The dog ate my homework!'
Free_Lun, lun

OpenW, lun, 'test_ascii_file_1.txt'
FOR j=0,N_Elements(strings)-1 DO PrintF, lun, strings[j]
Free_Lun, lun
Print, 'Time to rewrite file: ', systime(1) - start

END
;---------------------------------------------------

Cheers,

David

--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.idlcoyote.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
Re: Write to a certain line of a file [message #78957 is a reply to message #78956] Thu, 19 January 2012 09:49 Go to previous messageGo to next message
Michael Galloy is currently offline  Michael Galloy
Messages: 1114
Registered: April 2006
Senior Member
On 1/19/12 9:43 AM, Mark Piper wrote:
> On 1/19/2012 5:18 AM, Brian J. Daniel wrote:
>> I haven't done this, but POINT_LUN may do what you want. You'd need
>> to know the number of bytes per line. You will still have to read the
>> entire line, change the bit you want to change, move the LUN back to
>> the beginning of the line, and rewrite it.
>>
>> OpenR, LUN, filename, /Get_Lun
>> Point_Lun, LUN, line_number * bytes_per_line
>> tmp=''
>> ReadF, LUN, tmp
>> ; change the line as you see fit
>> new_line = tmp + 'changed line!'
>> Point_Lun, LUN, line_number * bytes_per_line
>> PrintF, LUN, new_line
>> Free_Lun, LUN
>>
>> Code is UNTESTED!
>
> To add to Brian's idea, if you have a text file, use SKIP_LUN with the
> LINES keyword set. A crude example:
>
> pro replace_line_ex
> compile_opt idl2
>
> f0 = 'ascii.txt'
> f1 = 'ascii-1.txt'
> file_copy, file_which(f0), f1, /overwrite
>
> nskip = 7
> line = ''
> replacement = 'My dog has fleas.'
>
> openu, u, f1, /get_lun
> skip_lun, u, nskip, /lines
> point_lun, -u, mark
> readf, u, line
> nchars = strlen(line)
> point_lun, u, mark
> printf, u, replacement, format='(a-' + strtrim(nchars,2) + ')'
> free_lun, u
> end
>
> Diff 'ascii.txt' in the example/data directory of the IDL distro with
> 'ascii-1.txt' in your working directory.

You are essentially treating the file as a binary file where you have
more options, but also more responsibility for keeping things straight.

Sure, this would work in the case where the new output has the exact
same length in bytes as the old output, but if not everything is going
to get screwed up. You could rewrite the file after the point of
insertion to fix this, but how much is it worth it to get around writing
this file?


Mike
--
Michael Galloy
www.michaelgalloy.com
Modern IDL, A Guide to Learning IDL: http://modernidl.idldev.com
Research Mathematician
Tech-X Corporation
Re: Write to a certain line of a file [message #78958 is a reply to message #78957] Thu, 19 January 2012 08:43 Go to previous messageGo to next message
Mark Piper is currently offline  Mark Piper
Messages: 198
Registered: December 2009
Senior Member
On 1/19/2012 5:18 AM, Brian J. Daniel wrote:
> I haven't done this, but POINT_LUN may do what you want. You'd need
> to know the number of bytes per line. You will still have to read the
> entire line, change the bit you want to change, move the LUN back to
> the beginning of the line, and rewrite it.
>
> OpenR, LUN, filename, /Get_Lun
> Point_Lun, LUN, line_number * bytes_per_line
> tmp=''
> ReadF, LUN, tmp
> ; change the line as you see fit
> new_line = tmp + 'changed line!'
> Point_Lun, LUN, line_number * bytes_per_line
> PrintF, LUN, new_line
> Free_Lun, LUN
>
> Code is UNTESTED!

To add to Brian's idea, if you have a text file, use SKIP_LUN with the
LINES keyword set. A crude example:

pro replace_line_ex
compile_opt idl2

f0 = 'ascii.txt'
f1 = 'ascii-1.txt'
file_copy, file_which(f0), f1, /overwrite

nskip = 7
line = ''
replacement = 'My dog has fleas.'

openu, u, f1, /get_lun
skip_lun, u, nskip, /lines
point_lun, -u, mark
readf, u, line
nchars = strlen(line)
point_lun, u, mark
printf, u, replacement, format='(a-' + strtrim(nchars,2) + ')'
free_lun, u
end

Diff 'ascii.txt' in the example/data directory of the IDL distro with
'ascii-1.txt' in your working directory.

mp
Re: Write to a certain line of a file [message #78959 is a reply to message #78958] Thu, 19 January 2012 04:18 Go to previous messageGo to next message
Brian Daniel is currently offline  Brian Daniel
Messages: 80
Registered: July 2009
Member
I haven't done this, but POINT_LUN may do what you want. You'd need
to know the number of bytes per line. You will still have to read the
entire line, change the bit you want to change, move the LUN back to
the beginning of the line, and rewrite it.

OpenR, LUN, filename, /Get_Lun
Point_Lun, LUN, line_number * bytes_per_line
tmp=''
ReadF, LUN, tmp
; change the line as you see fit
new_line = tmp + 'changed line!'
Point_Lun, LUN, line_number * bytes_per_line
PrintF, LUN, new_line
Free_Lun, LUN

Code is UNTESTED!
Re: Write to a certain line of a file [message #78960 is a reply to message #78959] Wed, 18 January 2012 18:02 Go to previous messageGo to next message
Brian Wolven is currently offline  Brian Wolven
Messages: 94
Registered: May 2011
Member
You *could* write C code using fseek, then compile it as a sharable object and call it from IDL. This is not likely to be much of an improvement, however. ;)
Re: Write to a certain line of a file [message #78961 is a reply to message #78960] Wed, 18 January 2012 17:16 Go to previous messageGo to next message
Matt Francis is currently offline  Matt Francis
Messages: 94
Registered: May 2010
Member
This all sounds very inefficient, in terms of the I/O overheads for a
single change. Is there really no other way of doing this in IDL?
Re: Write to a certain line of a file [message #78962 is a reply to message #78961] Wed, 18 January 2012 12:08 Go to previous messageGo to next message
Michael Galloy is currently offline  Michael Galloy
Messages: 1114
Registered: April 2006
Senior Member
On 1/18/12 12:49 PM, Zhang Bo wrote:
> Is there a way open a file and go to the nth line and change the
> content of this line, left the rest of file intact.

Read the file into a string array, change the nth line, and then write
the file back to the file.

Mike
--
Michael Galloy
www.michaelgalloy.com
Modern IDL, A Guide to Learning IDL: http://modernidl.idldev.com
Research Mathematician
Tech-X Corporation
Re: Write to a certain line of a file [message #78963 is a reply to message #78962] Wed, 18 January 2012 12:05 Go to previous messageGo to next message
natha is currently offline  natha
Messages: 482
Registered: October 2007
Senior Member
If the file is an ascii file you can read the file, modify the content
and then rewrite everything.

content=STRARR(FILE_LINES(file))

OPENR, lun, file, /GET_LUN
READU, lun, content
FREE_LUN, lun

;; then u modify the content
content[i]='new content'

;; rewrite everything
OPENW, lun, file, /GET_LUN
PRINTF, lun, content
FRRE_LUN, lun

Cheers,
nara
Re: Write to a certain line of a file [message #79048 is a reply to message #78957] Fri, 20 January 2012 08:21 Go to previous message
Mark Piper is currently offline  Mark Piper
Messages: 198
Registered: December 2009
Senior Member
On 1/19/2012 10:49 AM, Michael Galloy wrote:
>
> You are essentially treating the file as a binary file where you have
> more options, but also more responsibility for keeping things straight.
>
> Sure, this would work in the case where the new output has the exact
> same length in bytes as the old output, but if not everything is going
> to get screwed up. You could rewrite the file after the point of
> insertion to fix this, but how much is it worth it to get around writing
> this file?
>
>
> Mike

Ah, nuts! Yeah, I understand. I guess it's moot anyway because, as David
has shown, it's trivial to read/replace/rewrite a text file.

mp
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: confidence level
Next Topic: Write to a certain line of a file

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 17:12:10 PDT 2025

Total time taken to generate the page: 0.01093 seconds