69 lines
1.5 KiB
Python
69 lines
1.5 KiB
Python
"""Compare files."""
|
|
|
|
import os, stat, statcache
|
|
|
|
_cache = {}
|
|
BUFSIZE=8*1024
|
|
|
|
def cmp(f1, f2, shallow=1,use_statcache=0):
|
|
"""Compare two files.
|
|
|
|
Arguments:
|
|
|
|
f1 -- First file name
|
|
|
|
f2 -- Second file name
|
|
|
|
shallow -- Just check stat signature (do not read the files).
|
|
defaults to 1.
|
|
|
|
use_statcache -- Do not stat() each file directly: go through
|
|
the statcache module for more efficiency.
|
|
|
|
Return value:
|
|
|
|
integer -- 1 if the files are the same, 0 otherwise.
|
|
|
|
This function uses a cache for past comparisons and the results,
|
|
with a cache invalidation mechanism relying on stale signatures.
|
|
Of course, if 'use_statcache' is true, this mechanism is defeated,
|
|
and the cache will never grow stale.
|
|
|
|
"""
|
|
if use_statcache:
|
|
stat_function = statcache.stat
|
|
else:
|
|
stat_function = os.stat
|
|
s1 = _sig(stat_function(f1))
|
|
s2 = _sig(stat_function(f2))
|
|
if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG:
|
|
return 0
|
|
if shallow and s1 == s2:
|
|
return 1
|
|
if s1[1] != s2[1]:
|
|
return 0
|
|
|
|
result = _cache.get((f1, f2))
|
|
if result and (s1, s2) == result[:2]:
|
|
return result[2]
|
|
outcome = _do_cmp(f1, f2)
|
|
_cache[f1, f2] = s1, s2, outcome
|
|
return outcome
|
|
|
|
def _sig(st):
|
|
return (stat.S_IFMT(st[stat.ST_MODE]),
|
|
st[stat.ST_SIZE],
|
|
st[stat.ST_MTIME])
|
|
|
|
def _do_cmp(f1, f2):
|
|
bufsize = BUFSIZE
|
|
fp1 = open(f1, 'rb')
|
|
fp2 = open(f2, 'rb')
|
|
while 1:
|
|
b1 = fp1.read(bufsize)
|
|
b2 = fp2.read(bufsize)
|
|
if b1 != b2:
|
|
return 0
|
|
if not b1:
|
|
return 1
|