/// <inheritdoc /> public IEnumerable <FileInfo> EnumerateFiles(AbsolutePath path, EnumerateOptions options) { path.ThrowIfPathTooLong(); var dirInfo = new DirectoryInfo(path.Path); foreach (System.IO.FileInfo fi in dirInfo.EnumerateFiles( "*", (options & EnumerateOptions.Recurse) != 0 ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { bool foundValidFile = false; FileInfo newFi = default(FileInfo); try { newFi = new FileInfo { FullPath = new AbsolutePath(fi.FullName), Length = fi.Length }; foundValidFile = true; } catch (FileNotFoundException) { // Ignore FileNotFoundException here. EnumerateFiles returns a cached FileInfo and does not validate // whether the underlying file exists. Calling Length on this FileInfo for the first time prompts it to // refresh its properties/fields, leading to a FileNotFoundException if the file no longer exists. } if (foundValidFile) { yield return(newFi); } } }
private async Task <(bool isValid, string error)> ValidateFileAsync(Context context, ContentHash expectedHash, FileInfo fileInfo) { try { var path = fileInfo.FullPath; // The cache entry is invalid if the size in content directory doesn't mach an actual size if (_contentStoreInternal.TryGetFileInfo(expectedHash, out var contentFileInfo) && contentFileInfo.FileSize != fileInfo.Length) { return(isValid : false, error : $"File size mismatch. Expected size is {contentFileInfo.FileSize} and size on disk is {fileInfo.Length}."); } // Or if the content doesn't match the hash. var actualHashAndSize = await _contentStoreInternal.TryHashFileAsync(context, path, expectedHash.HashType); if (actualHashAndSize != null && actualHashAndSize.Value.Hash != expectedHash) { // Don't need to add an expected hash into the error string because the client code will always put it into the final error message. return(isValid : false, error : $"Hash mismatch. Actual hash is {actualHashAndSize.Value.Hash.ToShortString()}"); } return(isValid : true, error : string.Empty); } catch (Exception e) { _tracer.Warning(context, $"SelfCheck: Content hash is invalid. Hash={expectedHash.ToShortString()}, Error={e}"); return(isValid : true, error : string.Empty); } }