[newbie] Read file, and append?

G

Gilles Ganault

Hello

I'd just like to open each file in a directory with a given extension,
read it to search for a pattern, and, if not found, append data to
this file. The following doesn't work:

======
import glob,re

f = open("activate.tmpl", "r")
template = f.read()
template = "\r\n" + template
f.close()

for file in glob.glob('*.frm'):
#BAD f = open(file, "r+")
#f = open(file, "r")
#f = open(file, "a")

f = open(file, "rw")
if not re.search('Form_Activate',f.read(), re.I):
#print "Not in " + file

#IOError: [Errno 0] Error
f.write(template)

f.close()
======

What am I doing wrong?

Thank you.
 
G

Gary Herron

Gilles said:
Hello

I'd just like to open each file in a directory with a given extension,
read it to search for a pattern, and, if not found, append data to
this file. The following doesn't work:

======
import glob,re

f = open("activate.tmpl", "r")
template = f.read()
template = "\r\n" + template
f.close()

for file in glob.glob('*.frm'):
#BAD f = open(file, "r+")
#f = open(file, "r")
#f = open(file, "a")

f = open(file, "rw")
if not re.search('Form_Activate',f.read(), re.I):
#print "Not in " + file

#IOError: [Errno 0] Error
f.write(template)

f.close()
======

What am I doing wrong?
I've never used "rw" mode, and suspect that's the cause of your
problems here. I see no need for it here. Since you are going
to read the whole file in at once, you might as well write it (plus
the modification) all out again.

Also I notice that your close is called only if the pattern is not
found, even though you should call it for *every* file opened.

Also, you are not using the regular expression machinery as intended.
You are really just searching for a know and constant substring. Use
"in" instead.

Also I *always* read in binary mode (thereby forcing Windows to keep
it's damn hands off my bytes).

Also, don't use variables named 'file'. That overrides an important
builtin.

Here's what I'd end up with. (This is untested.)


import glob

f = open("activate.tmpl", "rb")
template = "\r\n" + f.read()
f.close()

for fname in glob.glob('*.frm'):
inf = open(fname, "rb")
content = inf.read()
inf.close()

if 'Form_Activate' not in content:
print "Not in", fname

outf = open(fname, 'wb')
outf.write(content)
outf.write(template)
outf.close()



Gary Herron
 
D

Dennis Lee Bieber

Hello

I'd just like to open each file in a directory with a given extension,
read it to search for a pattern, and, if not found, append data to
this file. The following doesn't work:
f = open(file, "rw")
if not re.search('Form_Activate',f.read(), re.I):
#print "Not in " + file

#IOError: [Errno 0] Error
f.write(template)

f.close()
======

What am I doing wrong?
Ignoring the question of the proper I/O mode, I believe the I/O
system MAY require one to perform a seek() when switching from read to
write and vice versa...
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
G

Gilles Ganault

Ignoring the question of the proper I/O mode, I believe the I/O
system MAY require one to perform a seek() when switching from read to
write and vice versa...

I thought about this, but I don't understand why I would need to do
this:

myfile=open('test.txt','r+')
content = myfile.read()
myfile.seek()
myfile.write('added this')
myfile.close

Is there really no way to read from a file and append data to it while
keeping the file open?

Also, I noticed a problem with the code given by Garry: When opening a
file in binary mode, the EOF character is 0A, while Windows apps
expect 0D0A. VisualBasic was not happy :)
 
D

Dennis Lee Bieber

myfile=open('test.txt','r+')
content = myfile.read()
myfile.seek()
myfile.write('added this')
myfile.close
Random
test data
for an
open, read, and
append test-=-=-=-=-
Random
test data
for an
open, read, and
append test
Stuff appended
-=-=-=-=-

Note that, in binary mode, "you" are responsible for every byte in the
file, including such things as line endings.
'Random\r\ntest data\r\nfor an\r\nopen, read, and\r\nappend test'

In binary mode, note that this file still has the M$ line endings of
\r\n AND note that there is NO EOF marker -- the file physically ended
after the t of test.

If you open the file in text mode, the \r\n gets translated to a
simple \n internally, and hence means positioning in the file does match
the number of bytes in the internal data.
Is there really no way to read from a file and append data to it while
keeping the file open?

Works for me, as long as one uses a seek() call when switching
between read and write...
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
J

John Machin

I thought about this, but I don't understand why I would need to do
this:

myfile=open('test.txt','r+')
content = myfile.read()
myfile.seek()

The above would not execute; seek needs at least one argument.
"Perform a seek()" was an abbreviated way of telling you to seek to
the position at which you want to write i.e. (current) end of file so
you would use seek(0, 2).

"Why": already explained; some stdio implementations require it.
myfile.write('added this')
myfile.close

Is there really no way to read from a file and append data to it while
keeping the file open?

Also, I noticed a problem with the code given by Garry: When opening a
file in binary mode, the EOF character is 0A, while Windows apps
expect 0D0A. VisualBasic was not happy :)

I'm sorry, but your statement of the alleged problem doesn't make much
sense. Possibly you mean EOL (end of line), not EOF (end of file). In
any case, when opening a file in binary mode, lines (and end-of-line
conventions) are quite irrelevant -- you use a_string = f.read(nbytes)
to read (or f.write(a_string) to write) as many bytes as you think you
need, starting at the current position in the file.

Perhaps if you provided more precise information than "VisualBasic was
not happy", like: the exact code that you ran, and the exact [hint:
use the repr() function] contents of the two input files and the
output file, plus what you expected the contents of the output file to
be, plus whatever VB had to say about the output file, we might be
able to help you with the problem.

Cheers,
John
 
G

Gilles Ganault

Works for me, as long as one uses a seek() call when switching
between read and write...

Thanks, Dennis. Worked :) I just changed the access mode from binary
to text so that Python handles the EOL character correctly, ie. CRLF
for Windows instead of LF for *nix.

For those interested, here's some working code in Windows +
ActivePython:

==========
import glob

#activate.tmpl contains the stuff I want to append to each file
f = open("activate.tmpl", "r")
template = "\n\n" + f.read()
f.close()

for frm in glob.glob('*.frm'):
f = open(frm, "r+")
content = f.read()
if 'Form_Activate' not in content:
f.seek(0,2)
f.write(template)
f.close()
==========
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top