def cached_hash_file(self):
try:
cache = self.ctx.cache_listdir_cache_hash_file
except AttributeError:
cache = self.ctx.cache_listdir_cache_hash_file = {}
if id(self.parent) in cache:
try:
t = cache[id(self.parent)][self.name]
except KeyError:
raise IOError('Not a file')
else:
# an opportunity to list the files and the timestamps at once
findData = ctypes.wintypes.WIN32_FIND_DATAW()
find = FindFirstFile(TP % self.parent.abspath(), ctypes.byref(findData))
if find == INVALID_HANDLE_VALUE:
cache[id(self.parent)] = {}
raise IOError('Not a file')
cache[id(self.parent)] = lst_files = {}
try:
while True:
if findData.cFileName not in UPPER_FOLDERS:
thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
if not thatsadir:
ts = findData.ftLastWriteTime
d = (ts.dwLowDateTime << 32) | ts.dwHighDateTime
lst_files[str(findData.cFileName)] = d
if not FindNextFile(find, ctypes.byref(findData)):
break
except Exception:
cache[id(self.parent)] = {}
raise IOError('Not a file')
finally:
FindClose(find)
t = lst_files[self.name]
fname = self.abspath()
if fname in Build.hashes_md5_tstamp:
if Build.hashes_md5_tstamp[fname][0] == t:
return Build.hashes_md5_tstamp[fname][1]
try:
fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT)
except OSError:
raise IOError('Cannot read from %r' % fname)
f = os.fdopen(fd, 'rb')
m = Utils.md5()
rb = 1
try:
while rb:
rb = f.read(200000)
m.update(rb)
finally:
f.close()
# ensure that the cache is overwritten
Build.hashes_md5_tstamp[fname] = (t, m.digest())
return m.digest()
评论列表
文章目录