Форум: "KOL";
Текущий архив: 2009.07.26;
Скачать: [xml.tar.bz2];
ВнизКак быстро сравнить два файла? Найти похожие ветки
← →
andreil © (2008-02-26 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 © (2008-02-27 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 © (2008-02-27 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 © (2008-02-27 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 © (2008-02-27 15:54) [4]Неа, сильно медленный :( Тот кусок, что я привел повыше перевирал 3Гб за 15 минут, а этот код - за час, не меньше :(
← →
Dimaxx © (2008-02-27 16:39) [5]Ну а как ты хотел 2 файла по 3 гига в память пихать (даже 2 по 1,5 и то долго)... :)
← →
Palladin © (2008-02-27 17:32) [6]
> andreil © (27.02.08 15:54) [4]
ффигеть, как же"шь он у тебя 6 гигабайт то в память считал? ты волшебник? а ms1.size ты проверял? сколько же считалось то? а то приходил тут один волшебник... с волшебным файлом подкачки... и компилятором делфи под Win512... тоже гигабайтами в память читал...
← →
Тыщ (2008-02-27 18:17) [7]Быстрей всего файлы читать с помощью File Mapping, кусками по 4 или 8 мб.
← →
andreil © (2008-02-28 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 © (2008-02-28 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 © (2008-02-28 13:12) [10]
> NewReadFileStream(File1);
и
> CompareMem(@ms1.Memory, @ms2.Memory, ms1.Size)
Ничего необычного не замечаешь?
← →
Palladin © (2008-02-28 13:28) [11]кстати да... бред еще тот...
← →
D[u]fa (2008-02-28 16:05) [12]>да не можешь ты прочитать себе в память больше чем 2гб минус <скушанное твоей программой уже>, нет таких компиляторов для делфи
я чет про компиляторы не понял)
← →
Palladin © (2008-02-28 16:23) [13]
> D[u]fa (28.02.08 16:05) [12]
нет компиляторов делфи способных генерировать, исполняемые в 64разрядной среде, файлы
.NET - не рассматриваем
← →
Palladin © (2008-02-28 16:24) [14]*в нативной 64 разрядной среде, без всяких эмуляций 32 разрядов
← →
D[u]fa (2008-02-28 20:18) [15]а ТСу надо в 64 разрядной среде файлы сравнивать?
видимо я не заметил
← →
Palladin © (2008-02-29 11:23) [16]какому ТСу? ты о чем вообще? и чего ты не заметил? я лишь сказал что приложение может использование более 2Гб (более 3Гб при использовании AWE) только при наличии 64разрядной адресации памяти. хотя автор заявляет что у него за 15 минут считались и сравнились 2(два) 3х (трех) гигабайтных (гигабайтных) файла (итого 6 гигабайт) в адресном пространстве его приложения. как ты думаешь с чего вдруг я завел разговор о волшебниках? чего тебе еще непонятно?
← →
andreil © (2008-02-29 11:49) [17]
> А где тебе говорили про ФАЙЛ, а не ФАЙЛЫ? чудикда не можешь
> ты прочитать себе в память больше чем 2гб минус <скушанное
> твоей программой уже>, нет таких компиляторов для делфи
Да тутже:
> ффигеть, как же"шь он у тебя 6 гигабайт то в память считал?
> ты волшебник? а ms1.size ты проверял? сколько же считалось
> то? а то приходил тут один волшебник... с волшебным файлом
> подкачки... и компилятором делфи под Win512... тоже гигабайтами
> в память читал...
:)
А за код - спасибо, посмотрим на скорость...
← →
Palladin © (2008-02-29 12:03) [18]
> ффигеть, как же"шь он у тебя 6 гигабайт то в память считал?
он это имеется ввиду код, 6Гб это имеется в виду 2 файла по 3 гигабайта, почему это невозможно см пост выше.
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2009.07.26;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c