Можно ли как-то проверить файла на копию другого файла?

Есть два файла, один является копией другого , и у них разные имена но имена не важно так как они могут быть одинаковые , как правильно проверить является ли один копией , пробовал через сравнивание ReadBytesAsync , но возвращает false при сравнивании. Использую StorageFile/StorageFolder.


Ответы (1 шт):

Автор решения: tym32167

Я не знаю, как там в UWP, но вот накатал пример для сравнивания простым фрейморком. Идея простая как гвоздь - сраниваем имя файлоа, потом размер, потом контент.

public class FileEqualsChecker
{
    public async Task<bool> IsSameFile(string fname1, string fname2)
    {
        if (string.CompareOrdinal(fname1, fname2) == 0) return true;
        if (!IsSameSize(fname1, fname2)) return false;
        return await IsSameContent(fname1, fname2);
    }

    private bool IsSameSize(string fname1, string fname2)
    {
        var finfo1 = new FileInfo(fname1);
        var finfo2 = new FileInfo(fname2);
        return finfo1.Length == finfo2.Length;
    }

размер блока 1 мегабайт, можете менять как вам надо

    private const int BLOCK_SIZE = 1 * 1024 * 1024;
    private async Task<bool> IsSameContent(string fname1, string fname2)
    {
        var block1 = new byte[BLOCK_SIZE];
        var block2 = new byte[BLOCK_SIZE];

        using (var sr1 = CreateStream(fname1))
        using (var sr2 = CreateStream(fname2))
        {
            int l1 = 0, l2 = 0;
            do
            {
                l1 = await sr1.ReadAsync(block1, 0, block1.Length);
                l2 = await sr2.ReadAsync(block2, 0, block2.Length);

                if (l1 != l2) return false;
                for (int i = 0; i < l1; i++)
                    if (block1[i] != block2[i]) return false;   

            } while (l1 > 0 && l2 > 0);
        }
        return true;
    }

читаем с буфером в 10 мегабайт. Выбирайте размер буфера по своему желанию

    private const int BUFFER_SIZE = 10 * 1024 * 1024;
    private Stream CreateStream(string fname) =>
        new BufferedStream(File.OpenRead(fname), BUFFER_SIZE);  
}

Проверка

var f1 = @"D:\temp\data.sql"; // 90 мб
var f2 = @"D:\temp\data - Copy.sql";  // 90 мб
var f3 = @"D:\temp\data3.sql";  // 20 мб
var f4 = @"D:\temp\Database.sdf";  // 200 мб

var checker = new FileEqualsChecker();

Console.WriteLine($"{f1} {f2} = {await checker.IsSameFile(f1, f2)}");
Console.WriteLine($"{f2} {f3} = {await checker.IsSameFile(f2, f3)}");
Console.WriteLine($"{f3} {f4} = {await checker.IsSameFile(f3, f4)}");
Console.WriteLine($"{f4} {f4} = {await checker.IsSameFile(f4, f4)}");

Вывод

D:\temp\data.sql D:\temp\data - Copy.sql = True
D:\temp\data - Copy.sql D:\temp\data3.sql = False
D:\temp\data3.sql D:\temp\Database.sdf = False
D:\temp\Database.sdf D:\temp\Database.sdf = True
→ Ссылка