import datetime import os import os.path import time # os.scandir() Windows bug dir_entry.stat() not works on file during writing. # Such files is for example application log. # No problem with os.stat() # Call of os.stat() before os.scandir() -> dir_entry.stat() is workaround. # Open file during writing other program "fixes" dir_entry.stat(). # Get properties on open file during writing "fixes" dir_entry.stat(). # Notice that I run os.scandir() separately so dir_entry.stat() is not cached. # Steps to reproduce lack of modification update: # 1. Close all explorers or other application using PATH (it has impact). # 2. Set PATH to test folder can be directory or windows share. # 3. Run program without DO_STAT (False). # # Alternative steps (external app force valid modification date): # 4. run 'touch' or 'echo' on file should "fix" problem. 'echo' will throw error not matter. # # Alternative scenario (os.stat() force valid modification date - very slow): # 3. Run program without DO_STAT (True). No problems. # # Error result: # Modification date from dir_entry.stat() is stalled (not changing after modification) # if os.stat() or other Windows application not read file. # # Excepted result: # Modification date from dir_entry.stat() is update from separate calls os.scandir() # or cached if it is same os.scandir() call. # # Notice that os.scandir() must be call before dir_entry.stat() to avoid caching as described in documentation. # And this is done but not work on files during writing.. # # Ask question if you have since is very hard to find bug. PATH = r'T:\\' FILE_NAME = r'test.txt' # PATH = r'\\nsdptrm01\d$\tmp' # FILE_NAME = r'test.txt' DO_STAT = True def scan(): with os.scandir(PATH) as dir_entries_iter: for dir_entry in dir_entries_iter: if dir_entry.path.endswith(FILE_NAME): stat_result = dir_entry.stat() print('dir_entry.stat()', dir_entry.path, stat_result.st_mtime, 'since last change', datetime.datetime.now().timestamp() - stat_result.st_mtime) if DO_STAT: stat_result = os.stat(dir_entry.path) print('os.stat()', dir_entry.path, stat_result.st_mtime) # mtime = os.path.getmtime(dir_entry.path) # size = os.path.getsize(dir_entry.path) # print('os.path', dir_entry.path, mtime, size) with open(f'{PATH}\\{FILE_NAME}', 'w') as f: while True: scan() now = datetime.datetime.now() print(now, now.timestamp()) f.write(str(now) + '\n') f.flush() time.sleep(1.0)