Reputation: 41
I am new to Python and going through the book of Zed. I stumbled upon the following exercise, scope of which is to copy one txt to another.
The original code from the book works perfectly and I copy below - so that I can show the difference:
1 from sys import argv
2 from os.path import exists
3
4 script, from_file, to_file = argv
5
6 print "Copying from %s to %s" % (from_file, to_file)
7
8 # we could do these two on one line too, how?
9 in_file = open(from_file)
10 indata = in_file.read()
11
12 print "The input file is %d bytes long" % len(indata)
13
14 print "Does the output file exist? %r" % exists(to_file)
15 print "Ready, hit RETURN to continue, CTRL- C to abort."
16 raw_input()
17
18 out_file = open(to_file, 'w')
19 out_file.write(indata)
20
21 print "Alright, all done."
22
23 out_file.close()
24 in_file.close()
What I decided to do, is to avoid having a variable in_file AND indata so I did some changes in lines 9-10, 12 and 19 and wrote the following code:
from sys import argv
from os.path import exists
script, from_file, to_file = argv
print "Copying from %s to %s" % (from_file, to_file)
# we could do these two on one line too, how?
in_file = open(from_file)
print "The input file is %d bytes long" % len(in_file.read())
print "Does the output file exist? %r" % exists(to_file)
print "Ready, hit RETURN to continue, CTRL- C to abort."
raw_input()
out_file = open(to_file, 'w')
out_file.write(in_file.read())
print "Alright, all done."
out_file.close()
in_file.close()
My problem is:
1) As written the amended code, althouhg it prints correctly the bytes of the in_file.read(), it never copies the text from the from_file to the to_file
2) If in the amended I ommit only the line which counts the bytes - so the len() function - then it copies normally the one file to the other .
From my understanding, by evoking the len() function it then closes the in_file.
Is my thought correct? Can I avoid that, by not having to repeat the code in_file = open(from_file)? What else could be the reason?
I would appreciate the help, because this drives me a bit nuts :)
Upvotes: 4
Views: 187
Reputation: 11391
It's actually the act of calling in_file.read()
twice that's causing your problem. You can fix it by assigning the result to a variable, as in the original:
indata = in_file.read()
The reason is that when you call in_file.read()
, you "exhaust" the file. Think of the file as a book - as the computer reads it, it leaves a bookmark where it leaves off. So when it's done, the bookmark is left on the last page of the book. And when you call in_file.read()
the second time, python starts where the bookmark was left - at the end, with no more pages left to read.
If you want to avoid creating a variable for some reason, you could "move the bookmark" back to the beginning of the file, as suggested by @WayneWerner in the comments.
in_file.seek(0)
Upvotes: 2