'How to watch the file change and compare the two files in python?
I have a requirement where I need to do the following:
Watch a file for any changes - done
Compare the file with the changed file - pending
- That means, say I have a text file with the content "hello world" as below:
hello.txt
hello world
Then I will add another line to the same file as below
hello world
some other line
up on the save, it should create a new file without actually writing to the same file so, I should end up with two files instead of one:
hello.txt- original file
hello world
hello_modified.txt- modified (appended) file
hello world
some other
How can I do this with python ?
I have already used watchdog for listening to file modification, I have even implemented the function to display the diff between the two files too. But I have no idea how to write the logic for the file replication. i.e. how can I create and write to another file up on saving the hello.txt without really saving the hello.txt ?
Solution 1:[1]
I think you can do this by using a while loop and time module. Note that, reading a file each time a while statements loops over itself, is probitively expensive for your computer processor. So, in this answer, I decided to check the files every 3 seconds.
from time import time
startTime = time()
diffTime = 3
with open("hello.txt") as f:
checkFile = f.read()
while True:
now = time()
if now > startTime+diffTime:
startTime = now
with open("hello.txt") as f:
myString = f.read()
if checkFile != myString:
with open("hello_modified.txt", "w") as f:
f.write(myString)
with open("hello.txt", "w") as f:
f.write(checkFile)
Solution 2:[2]
Here's an implementation using a coroutine file_copier. See usage and test for usage.
import itertools
from pathlib import Path
import shutil
def copy(src: Path, dst: Path):
print(f"Copying {src} to {dst}")
shutil.copyfile(src, dst)
def file_copier(watched_path: str|Path):
if isinstance(watched_path, str):
watched_path = Path(watched_path)
shutil.copyfile(watched_path, watched_path.with_stem(f'{watched_path.stem}_0'))
for counter in itertools.count():
yield
copy(watched_path, watched_path.with_stem(f'{watched_path.stem}_{counter+1}'))
copy(watched_path.with_stem(f'{watched_path.stem}_{counter}'), watched_path)
path = Path("hello.txt")
def usage():
fc = file_copier(path)
next(fc) # start/init
# When 'hello.txt' has been modified:
next(fc) # copies 'hello.txt' to new history file and resets 'hello.txt' to previous history file
# TEST
def create():
"""Creates empty 'hello.txt'"""
with open(path, "w") as f:
pass
def append(line: str):
"""Simulates modification of 'hello.txt'"""
with open("hello.txt", "a") as f:
print(line, file=f)
def test():
fc = file_copier(path)
create()
append("hello world")
next(fc)
append("edit 1")
next(fc)
append("edit 2")
next(fc)
append("edit 3")
next(fc)
if __name__ == '__main__':
test()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Amirhossein Kiani |
| Solution 2 |
