1c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien#!/usr/bin/env python 2c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 3c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chienimport os 4c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chienimport shutil 5c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chienimport sys 6c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 7c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan ChienBUFFER_SIZE = 1024 8c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 9c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chiendef is_file_different(a, b): 10c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if os.path.getsize(a) != os.path.getsize(b): 11c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # If the file size is different, the content must be different. 12c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien return True 13c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 14c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # Read the content of the files, and compare them. 152010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao result = False 162010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao 172010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao fa = open(a, 'rb') 182010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao fb = open(b, 'rb') 192010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao 202010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao while True: 212010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao buff_a = fa.read(BUFFER_SIZE) 222010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao buff_b = fb.read(BUFFER_SIZE) 232010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao 242010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao if buff_a != buff_b: 252010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao # File is different in this block. 262010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao result = True 272010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao break 28c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 292010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao if len(buff_a) < BUFFER_SIZE: 302010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao # Finished 312010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao break 32c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 332010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao fa.close() 342010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao fb.close() 35c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 36c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # File is the same. 372010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao return result 38c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 39c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chiendef copyfile(src, dest): 40c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if not os.path.exists(src): 41c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien raise ValueError('Source file not found') 42c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 43c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # Make parent directory (if necessary) 44c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien destdir = os.path.dirname(dest) 45c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if not os.path.exists(destdir): 46c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien try: 47c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien os.makedirs(destdir) 4812c27e38e875ae53f47e4a1b1c00a601457c20f2Shih-wei Liao except os.error, e: 49c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien raise ValueError('Unable to create directory ' + destdir) 50c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien elif not os.path.isdir(destdir): 51c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien raise ValueError(destdir + ' is not a directory') 52c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 53c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if not os.path.exists(dest) or is_file_different(src, dest): 54c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # If the destination file does not exist or the source file is 55c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien # different from the destination file, then we copy the file. 56c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien shutil.copyfile(src, dest) 57c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 58c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chiendef main(): 59c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if len(sys.argv) < 3: 602010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao print >> sys.stderr, 'USAGE:', sys.argv[0], '<srcfile> <destfile>' 61c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien sys.exit(1) 62c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 63c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien srcfile = os.path.abspath(sys.argv[1]) 64c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien destfile = os.path.abspath(sys.argv[2]) 65c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 66c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien if srcfile == destfile: 672010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao print >> sys.stderr, 'WARNING: <srcfile> is equal to <destfile>' 68c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien else: 69c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien try: 70c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien copyfile(srcfile, destfile) 7112c27e38e875ae53f47e4a1b1c00a601457c20f2Shih-wei Liao except ValueError, e: 722010bbd9e389c9745a03a21d1cfa87acacda6abbShih-wei Liao print >> sys.stderr, 'ERROR: ', e 73c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien sys.exit(1) 74c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien 75c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chienif __name__ == '__main__': 76c0a87ab7907e88efa4a5d7cba27e876f0dab1f5bLogan Chien main() 77