summaryrefslogtreecommitdiff
path: root/Lib/filecmp.py
blob: 24ae4b3b115b01fd64dccfd2da527b5794a11e78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""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