0

The context is the following one, I have two text file that I need to edit. I open the first text file read it line by line and edit it but sometimes when I encounter a specific line in the first text file I need to overwritte content of the the second file.

However, each time I re-open the second text file instead of overwritting its content the below code appends it to the file...

Thanks in advance.

def edit_custom_class(custom_class_path, my_message):
    with open(custom_class_path, "r+") as file: 
        file.seek(0)
        for line in file:
            if(some_condition):
                file.write(mu_message)

def process_file(file_path):
     with open(file_path, "r+") as file:    
        for line in file:
            if(some_condition):
                edit_custom_class(custom_class_path, my_message)
aress31
  • 340
  • 5
  • 20
  • Do you want to append or overwrite? – xrisk Jun 27 '15 at 10:27
  • 1
    Also that huge block of code is helping no one understand your problem. – xrisk Jun 27 '15 at 10:28
  • I want to overwritte it each time I enter to the method edit_custom_class(custom_class_path, my_tag, my_message) – aress31 Jun 27 '15 at 10:28
  • 1
    This will help others help you solve your problem: http://stackoverflow.com/help/mcve – Alex Huszagh Jun 27 '15 at 10:29
  • 1
    Have you tried using the `file.tell()` command? This will help you investigate where the file pointer currently is when you try to write. – Martin Evans Jun 27 '15 at 10:30
  • Wait, you are attempting to read _and_ write to the file at the same time? – xrisk Jun 27 '15 at 10:32
  • Why don’t you read it once, decide what needs to be changed (if anything), and then completely over-write the file? – xrisk Jun 27 '15 at 10:33
  • @MartinEvans thank you for the tip I did not know this method, the pointer tells me that at the end of each call of edit_custom_class(custom_class_path, my_tag, my_message) the pointer still stay at the end even if I call file.seek(0) this is really weird! – aress31 Jun 27 '15 at 10:35
  • @RishavKundu not at all I think I explained the context properly. I have two text file, I read the first text files each time I encounter a specific line in the first text file I edit the second one(I need to overwritte it completely). – aress31 Jun 27 '15 at 10:39
  • @LastBersekr you are attempting to modify the file as you read it `for line in file: if(some_condition): file.write(edit_line)` – xrisk Jun 27 '15 at 10:40
  • 1
    You could consider "rw" as the file mode. Note, writing to a file at a given offset does not insert, it overwrites. If you need to insert you might consider creating a new file and then deleting the current one when complete. – Martin Evans Jun 27 '15 at 10:41
  • @RishavKundu, yes I read a line and if this line matches the condition I overwritte it. I already did it with fileinput.input(file_path, inplace = True) and it was working perfectly but for some reason I want to use w with open(file_path, "r+") as file instead. – aress31 Jun 27 '15 at 10:44
  • @MartinEvans the point is that I need to overwritte and not insert at a given offset. With this code it inserts the new line at the end of my file when it should be supposed just to overwritte the given line with the new content... – aress31 Jun 27 '15 at 10:46
  • 1
    You can modify the original file using a tempfile of fileinput http://stackoverflow.com/a/30777077/2141635, if you reopen the file with `w` and your code errors you lose everything – Padraic Cunningham Jun 27 '15 at 11:21

1 Answers1

0

In my opinion, simultaneously reading and modifying a file is a bad thing to do. Consider using something like this. First read the file, make modifications, and then overwrite the file completely.

def modify(path):
    out = []
    f = open(path)
    for line in f:
        if some_condition:
            out.append(edited_line) #make sure it has a \n at the end
        else:
            out.append(original_line)
    f.close()
    with open(path,'w') as f:
        for line in out:
            f.write(line)
xrisk
  • 3,790
  • 22
  • 45
  • I think that could solve my problem but I would like to know why you consider it as a bad solution to read and write simultaneously in a file. Also, why with for line in fileinput.input(file_path, inplace = True) I am able to read and modify the file simultaneously without any problem. Thanks – aress31 Jun 27 '15 at 10:51
  • Hm, there is no reason for it as such. I like simple solutions to things. – xrisk Jun 27 '15 at 10:54
  • 1
    But you may find this link interesting http://stackoverflow.com/questions/5453267/is-it-possible-to-modify-lines-in-a-file-in-place – xrisk Jun 27 '15 at 10:55
  • Most of the answers recommend not doing it, hehe. And by the way, if you look at https://docs.python.org/2/library/fileinput.html#fileinput.FileInput they are doing the same thing as here. – xrisk Jun 27 '15 at 10:58
  • i.e. using a “buffer” of some sort, when using `inplace= True` – xrisk Jun 27 '15 at 10:59
  • 2
    You convinced me to go for this solution. Thanks for your help. – aress31 Jun 27 '15 at 11:01
  • 1
    This is not a good approach either as if anything happens after opening with `w` then you lose all your data – Padraic Cunningham Jun 27 '15 at 11:24
  • @PadraicCunningham then what is the best approach? :) I’m a beginner sorry. – xrisk Jun 27 '15 at 11:25
  • The second part of this answer http://stackoverflow.com/questions/30776900/python-how-to-add-a-space-string-to-the-end-of-every-line-in-a-text-conf/30777077#30777077 – Padraic Cunningham Jun 27 '15 at 11:26
  • @PadraicCunningham and why is that method guaranteed to work? – xrisk Jun 27 '15 at 11:29
  • @PadraicCunningham I don’t know what that means but I will ask OP to look into your answer. – xrisk Jun 27 '15 at 11:33
  • @LastBerserkr please look at the answer which PadraicCunningham has linked to. – xrisk Jun 27 '15 at 11:34
  • @RishavKundu. http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html that is what move is doing – Padraic Cunningham Jun 27 '15 at 11:39
  • 1
    Thanks for helping me to get the best solution. :) – aress31 Jun 27 '15 at 11:40
  • @PadraicCunningham anyway the solution of Rishav Kundu should be fine because you say I can loose everything after opening the with 'w' but you forget that the statement with open as handle all kind of errors so in a case of a lost of data that will raise an error, right? – aress31 Jun 27 '15 at 11:46
  • 2
    @LastBerserkr, nope, once open gets called with `w` your file is overwritten so you lose all your data – Padraic Cunningham Jun 27 '15 at 11:48
  • @LastBerserkr what he means is that, if there is an error while writing to the file, then you will lose all the data you had in the original file – xrisk Jun 27 '15 at 11:49
  • The best thing to do is first write to a temporary file, and then _rename_ the temporary file – xrisk Jun 27 '15 at 11:49
  • Ok, I see, so nothing change from your code except that I write to an other temp file instead and at the end I rename the file, right? – aress31 Jun 27 '15 at 11:55