Конференция "KOL" » Как быстро сравнить два файла? [Delphi, Windows]
 
  • andreil © (26.02.08 20:26) [0]
    Для VCL это выглядело следующим образом:
    function CompareFiles(const File1, File2:TFileName): boolean;
    var
     ms1, ms2: pStream;
    begin
     Result:=False;
     ms1:=TMemoryStream.Create;
     try
       ms1.LoadFromFile(File1);
       ms2:=TMemoryStream.Create;
       try
         ms2.LoadFromFile(File2);
         if ms1.Size=ms2.Size then Result:=CompareMem(ms1.Memory, ms2.Memory, ms1.Size);
       finally
         ms2.Free;
       end;
     finally
       ms1.Free;
     end
    end;



    Мне хотелось бы узнать, как такое можно сделать на КОЛ, если вообще возможно. И желательно - потоками, тк они быстрее работают.
  • Jon © (27.02.08 00:18) [1]
    function CompareFiles(const File1, File2: String): Boolean;
    var
     fs1, fs2, ms1, ms2: PStream;
    begin
     Result := False;
     fs1 := NewReadFileStream(File1);
     fs2 := NewReadFileStream(File2);
     ms1 := NewMemoryStream;
     ms2 := NewMemoryStream;
     Stream2Stream(ms1, fs1, fs1.Size);
     Stream2Stream(ms2, fs2, fs2.Size);
     if ms1.Size = ms2.Size then
       Result := CompareMem(ms1.Memory, ms2.Memory, ms1.Size);
     ms2.Free;
     ms1.Free;
     fs2.Free;
     fs1.Free
    end;

  • andreil © (27.02.08 08:51) [2]

    > function CompareFiles(const File1, File2: String): Boolean;
    > var  fs1, fs2, ms1, ms2: PStream;begin  Result := False;
    >   fs1 := NewReadFileStream(File1);  fs2 := NewReadFileStream(File2);
    >   ms1 := NewMemoryStream;  ms2 := NewMemoryStream;  Stream2Stream(ms1,
    >  fs1, fs1.Size);  Stream2Stream(ms2, fs2, fs2.Size);  if
    > ms1.Size = ms2.Size then    Result := CompareMem(ms1.Memory,
    >  ms2.Memory, ms1.Size);  ms2.Free;  ms1.Free;  fs2.Free;
    >   fs1.Freeend;


    Вылетает с ошибкой после первого же обращеня :(. Те до конца доходит и все - ошибка :(
  • Palladin © (27.02.08 12:16) [3]
    потоки быстрее работают... от ведь... а мужики то и не знают...

    Function CompareFiles(Const p_strFileName1,p_strFileName2:String):Boolean;
    Const
    BUF_SIZE=1024*1024;
    Var
     f1,f2:File;
     buf1,buf2:Pointer;
     n1,n2:Integer;
    Begin
     AssignFile(f1,p_strFileName1);Reset(f1,1);
     AssignFile(f2,p_strFileName2);Reset(f2,1);
     Result:=FileSize(f1)=FileSize(f2);
     If Result Then
      Begin
       GetMem(Buf1,BUF_SIZE); GetMem(Buf2,BUF_SIZE);
       Try
        Repeat
         BlockRead(f1,Buf1^,BUF_SIZE,n);
         BlockRead(f2,Buf2^,BUF_SIZE,n);
         Result:=CompareMem(Buf1,Buf2,n);
         If Not Result Then Break;
        Until n=0;
       Finally
        FreeMem(Buf1); FreeMem(Buf2);
       End;
     CloseFile(f1);CloseFile(f2);
    End;

  • andreil © (27.02.08 15:54) [4]
    Неа, сильно медленный :( Тот кусок, что я привел повыше перевирал 3Гб за 15 минут, а этот код - за час, не меньше :(
  • Dimaxx © (27.02.08 16:39) [5]
    Ну а как ты хотел 2 файла по 3 гига в память пихать (даже 2 по 1,5 и то долго)... :)
  • Palladin © (27.02.08 17:32) [6]

    > andreil ©   (27.02.08 15:54) [4]

    ффигеть, как же'шь он у тебя 6 гигабайт то в память считал? ты волшебник? а ms1.size ты проверял? сколько же считалось то? а то приходил тут один волшебник... с волшебным файлом подкачки... и компилятором делфи под Win512... тоже гигабайтами в память читал...
  • Тыщ (27.02.08 18:17) [7]
    Быстрей всего файлы читать с помощью File Mapping, кусками по 4 или 8 мб.
  • andreil © (28.02.08 09:08) [8]
    Я имею ввиду ФАЙЛЫ, а не ФАЙЛ. Мне надо в программе сравнивать файлы игр для создания патчей. Для VCL'а у меня был набор функций для этого, а для KOL'а надо писать все самому ;) Просто я сделал так:
    function CompareFiles(const File1, File2:TFileName): boolean;
    var
     ms1, ms2: pStream;
    begin
     Result:=False;
     try
       ms1:=NewReadFileStream(File1);
       try
         ms2:=NewReadFileStream(File2);
         if ms1.Size=ms2.Size then Result:=CompareMem(@ms1.Memory, @ms2.Memory, ms1.Size);
       finally
         ms2.Free;
       end;
     finally
       ms1.Free;
     end
    end;



    но этот код практически всегда выдает несоответствие файов :(
  • Palladin © (28.02.08 11:37) [9]

    > Я имею ввиду ФАЙЛЫ, а не ФАЙЛ.

    А где тебе говорили про ФАЙЛ, а не ФАЙЛЫ? чудик
    да не можешь ты прочитать себе в память больше чем 2гб минус <скушанное твоей программой уже>, нет таких компиляторов для делфи

    Function CompareFiles2(Const p_strFileName1,p_strFileName2:String):Boolean;
    Const
    BUF_SIZE=32*1024*1024;

    Type
    TFileMapRec=Record
     _File:HFILE;
     _Map:THandle;
     _Size:Int64;
    End;

    Function OpenFile(Const p_strFileName:String):TFileMapRec;
    Var
     slo,shi:Cardinal;
    Begin
     Result._File:=CreateFile(PChar(p_strFileName),GENERIC_READ,FILE_SHARE_READ,Nil,O PEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
     slo:=Windows.GetFileSize(Result._File,@shi);
     Int64Rec(Result._Size).Lo:=slo;
     Int64Rec(Result._Size).Hi:=shi;
     Result._Map:=CreateFileMapping(Result._File,Nil,PAGE_READONLY,0,0,Nil);
    End;

    Procedure CloseFile(Var rp_rFile:TFileMapRec);
    Begin
     CloseHandle(rp_rFile._Map);
     CloseHandle(rp_rFile._File);
    End;

    Function MapBuff(p_rFile:TFileMapRec;p_nFrom:Int64;p_nCount:Cardinal):Pointer;
    Begin
     Result:=MapViewOfFile(p_rFile._Map,FILE_MAP_READ,Int64Rec(p_nFrom).Hi,Int64Rec(p _nFrom).Lo,p_nCount);
    End;

    Procedure UnMapBuff(Var p:Pointer);
    Begin
     UnmapViewOfFile(p);
    End;

    Var
    File1,File2:TFileMapRec;
    Buf1,Buf2:Pointer;
    p:Int64;

    Function Compare(p_nFrom:Int64;p_nCount:Cardinal):Boolean;
    Begin
     Buf1:=MapBuff(File1,p_nFrom,p_nCount);
     Try
      Buf2:=MapBuff(File2,p_nFrom,p_nCount);
      Try
       Result:=CompareMem(Buf1,Buf2,p_nCount);
      Finally
       UnMapBuff(Buf2);
      End;
     Finally
      UnMapBuff(Buf1);
     End;
    End;

    Begin
    File1:=OpenFile(p_strFileName1);
    Try
     File2:=OpenFile(p_strFileName2);
     Try
      Result:=File1._Size<>File2._Size;
      If Result Then Exit;
      p:=0;
      While True Do
       Begin
        If (p+BUF_SIZE)>File1._Size Then
         Begin
          Result:=Compare(p,File1._Size-p);
          Break;
         End Else
         Begin
          Result:=Compare(p,BUF_SIZE);
          If Not Result Then Break;
          Inc(p,BUF_SIZE);
         End;
       End;
     Finally
      CloseFile(File2);
     End;
    Finally
     CloseFile(File1);
    End;
    End;



    так должно побыстрее сравнить, пробуй
  • Dimaxx © (28.02.08 13:12) [10]

    > NewReadFileStream(File1);


    и


    > CompareMem(@ms1.Memory, @ms2.Memory, ms1.Size)

    Ничего необычного не замечаешь?
  • Palladin © (28.02.08 13:28) [11]
    кстати да... бред еще тот...
  • D[u]fa (28.02.08 16:05) [12]
    >да не можешь ты прочитать себе в память больше чем 2гб минус <скушанное твоей программой уже>, нет таких компиляторов для делфи

    я чет про компиляторы не понял)
  • Palladin © (28.02.08 16:23) [13]

    > D[u]fa   (28.02.08 16:05) [12]

    нет компиляторов делфи способных генерировать, исполняемые в 64разрядной среде, файлы

    .NET - не рассматриваем
  • Palladin © (28.02.08 16:24) [14]
    *в нативной 64 разрядной среде, без всяких эмуляций 32 разрядов
  • D[u]fa (28.02.08 20:18) [15]
    а ТСу надо в 64 разрядной среде файлы сравнивать?
    видимо я не заметил
  • Palladin © (29.02.08 11:23) [16]
    какому ТСу? ты о чем вообще? и чего ты не заметил? я лишь сказал что приложение может использование более 2Гб (более 3Гб при использовании AWE) только при наличии 64разрядной адресации памяти. хотя автор заявляет что у него за 15 минут считались и сравнились 2(два) 3х (трех) гигабайтных (гигабайтных) файла (итого 6 гигабайт) в адресном пространстве его приложения. как ты думаешь с чего вдруг я завел разговор о волшебниках? чего тебе еще непонятно?
  • andreil © (29.02.08 11:49) [17]

    > А где тебе говорили про ФАЙЛ, а не ФАЙЛЫ? чудикда не можешь
    > ты прочитать себе в память больше чем 2гб минус <скушанное
    > твоей программой уже>, нет таких компиляторов для делфи

    Да тутже:

    > ффигеть, как же'шь он у тебя 6 гигабайт то в память считал?
    >  ты волшебник? а ms1.size ты проверял? сколько же считалось
    > то? а то приходил тут один волшебник... с волшебным файлом
    > подкачки... и компилятором делфи под Win512... тоже гигабайтами
    > в память читал...

    :)

    А за код - спасибо, посмотрим на скорость...
  • Palladin © (29.02.08 12:03) [18]

    > ффигеть, как же'шь он у тебя 6 гигабайт то в память считал?

    он это имеется ввиду код, 6Гб это имеется в виду 2 файла по 3 гигабайта, почему это невозможно см пост выше.
 
Конференция "KOL" » Как быстро сравнить два файла? [Delphi, Windows]
Есть новые Нет новых   [134431   +15][b:0][p:0.003]