Truncating a text file does not modify the file

When a newbie (e.g. me) asks to read / process a text file in python, he often gets answers like:

with open("input.txt", 'r') as f: for line in f: #do your stuff 

Now I would like to truncate everything in the file that I read after the special line. After changing the above example, I use:

 with open("input.txt", 'r+') as file: for line in file: print line.rstrip("\n\r") #for debug if line.rstrip("\n\r")=="CC": print "truncating!" #for debug file.truncate(); break; 

and expect him to throw everything after the first "CC". Running this code on input.txt:

 AA CC DD 

the console displays (as expected) the following:

 AA CC truncating! 

but the file "input.txt" remains unchanged!?!?

How can it be? What am I doing wrong?

Edit: After the operation, I want the file to contain:

 AA CC 
+3
source share
2 answers

In addition to the glibdud request, truncate () requires a size from which it removes content. You can get the current position in your file with the tell() command. As he mentioned, using a for loop, next() disallows commands like tell. But in the suggested while-loop, you can trim the current tell () position. So the full code would look like this:

Python 3:

 with open("test.txt", 'r+') as file: line = file.readline() while line: print(line.strip()) if line.strip() == "CC": print("truncating") file.truncate(file.tell()) break line = file.readline() 
+3
source

It looks like you're falling prey to the read buffer used inside Python. From the document for the file.next () method :

A file object is its own iterator, for example iter(f) returns f (if f is not closed). When a file is used as an iterator, usually in a for loop (for example, for line in f: print line.strip() ), the next() method is called again. This method returns the next line of input or raises StopIteration when EOF hits when the file is open for reading (undefined behavior when the file is open for writing). To make the for loop the most efficient way to loop over lines in a file (a very common operation), the next() method uses a hidden read buffer. As a result of using the read buffer, combining next() with other file methods (e.g. readline() ) does not work correctly. However, using seek() to move the file to its absolute position will reset the read buffer.

The result is that the file position is not where you expect it to happen when you truncate. One way is to use readline to iterate over the file, not the iterator:

 line = file.readline() while line: ... line = file.readline() 
+5
source

Source: https://habr.com/ru/post/1240923/


All Articles