3

I am copying a large file, 2.23GB (2,401,129,714 bytes) from one location to another which is on a network share. I am using the below code to check when the file has finished copying by checking the file size. I am on Windows 7 Python 2.7.11 and os.path.getsize reports the full file size as soon as the file starts copying, the file doesn't grow. Is there another way to tell when a file has finished copying within Python?

copying = True
size2 = -1
while copying:
    size = os.path.getsize('name of file being copied')
    if size == size2:
        print "File has finished copying"
        break
    else:
        size2 = os.path.getsize('name of file being copied')
        time.sleep(2)
speedyrazor
  • 3,127
  • 7
  • 33
  • 51

3 Answers3

3

EDIT: Solution-

import os
import time
def main( event, path ):  
 if os.path.exists(path):
   while True:
    try:
        new_path= path + "_"
        os.rename(path,new_path)
        os.rename(new_path,path)
        time.sleep(0.05)
        print("event type: %s path: %s " %(event.event_type, path))
        break
    except OSError:
        time.sleep(0.05)

I utilized the fact that no two processes can simulatenously utilize a file for IO operations. In windows, when a file is copying, it is kept open by an OS process. Once copying is done, the file is closed by the OS process, and the os module in python can finally rename the file successfully

@Anmol- Not a duplicate. The issue with this code , in windows, is that the os reserves a binary file and writes over it while copying, and hence the size displayed by os.stat won't incrementally increase. We would want a piece of code that notifies us whenever image copying has completed. This particular code is a polling code which works well on linux, and notifies us when the copying process is done (in linux, the size increases incrementally with time)

import os
import time
def main( event,path ):    
  historicalSize = -1  
  while (historicalSize != os.path.getsize(path)):
    historicalSize = os.stat(path).st_size  
    print("Size now %s" %historicalSize)
    time.sleep(1)      
  else: print( "event type: %s path: %s " %(event.event_type, path)) 

Output should be like

Size now 124
Size now 12345
Size now 238590
.....

, instead of just

Size now 23459066950
Adithya V
  • 31
  • 3
1

You can use os.stat() as mentioned here.
See this for a great example on usage.

Anmol Singh Jaggi
  • 8,376
  • 4
  • 36
  • 77
  • os.stat() and os,path.getsize() display final allocated size the only solution is to try to execute your code and have a try catch block, and then sleep-retry – amstegraf Dec 18 '18 at 18:49
0

os.stat() and os,path.getsize() display final allocated size the only solution is to try to execute your code and have a try catch block, and then sleep-retry

This can also be used on Linux, and this way you don't bother to poll the size you just retry. Of course the code below should be improved a little to make sure you don't hit a infinit loop

       while True:
            try:
                shutil.copy2(src, dst)
                break
            except PermissionError:
                time.sleep(0.5)
amstegraf
  • 597
  • 1
  • 5
  • 11