main
cs 81 lines 2.96 KB
Raw
1 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Services;
10
11 internal class FileSystemManager
12 {
13 public FileSystemManager(IFileSystem fileSystem, IEnumerable<IFileSystemExtension> fileSystemExtensions)
14 {
15 this.FileSystem = fileSystem;
16 this.Extensions = fileSystemExtensions;
17 }
18
19 private IFileSystem FileSystem { get; }
20
21 private IEnumerable<IFileSystemExtension> Extensions { get; }
22
23 public bool CompareFiles(string firstPath, string secondPath)
24 {
25 foreach (var extension in this.Extensions)
26 {
27 var compared = extension.CompareFiles(firstPath, secondPath);
28 if (compared.HasValue)
29 {
30 return compared.Value;
31 }
32 }
33
34 return this.BuiltinCompareFiles(firstPath, secondPath);
35 }
36
37 private bool BuiltinCompareFiles(string firstPath, string secondPath)
38 {
39 if (String.Equals(firstPath, secondPath, StringComparison.OrdinalIgnoreCase))
40 {
41 return true;
42 }
43
44 using (var firstStream = this.FileSystem.OpenFile(null, firstPath, FileMode.Open, FileAccess.Read, FileShare.Read))
45 using (var secondStream = this.FileSystem.OpenFile(null, secondPath, FileMode.Open, FileAccess.Read, FileShare.Read))
46 {
47 if (firstStream.Length != secondStream.Length)
48 {
49 return false;
50 }
51
52 // Using a larger buffer than the default buffer of 4 * 1024 used by FileStream.ReadByte improves performance.
53 // The buffer size is based on user feedback. Based on performance results, a better buffer size may be determined.
54 var firstBuffer = new byte[16 * 1024];
55 var secondBuffer = new byte[16 * 1024];
56
57 var firstReadLength = 0;
58 do
59 {
60 firstReadLength = firstStream.Read(firstBuffer, 0, firstBuffer.Length);
61 var secondReadLength = secondStream.Read(secondBuffer, 0, secondBuffer.Length);
62
63 if (firstReadLength != secondReadLength)
64 {
65 return false;
66 }
67
68 for (var i = 0; i < firstReadLength; ++i)
69 {
70 if (firstBuffer[i] != secondBuffer[i])
71 {
72 return false;
73 }
74 }
75 } while (0 < firstReadLength);
76 }
77
78 return true;
79 }
80 }
81 }