जवाब 99% मामलों में काम कर रहे हैं, लेकिन वहाँ अतिरिक्त जांच किए जाने के लिए कर रहे हैं!
TStream के वंशज लगभग कुछ भी हो सकता है, इसलिए यह गारंटी नहीं है कि Stream.Read डेटा की एक ही राशि वापस आ जाएगी, भले ही धाराओं में एक ही लंबाई (धारा वंशज भी डेटा डाउनलोड कर रहे हैं, तो वापस आ सकते हैं READED = अगले बांक की प्रतीक्षा करते समय 0 बाइट्स)। धाराएं पूरी तरह से अलग मीडिया पर भी हो सकती हैं और स्ट्रीम पढ़ने में त्रुटि केवल एक पर हो सकती है।
100% कार्य कोड के लिए ये सभी चेक किए जाने चाहिए। मैंने माइक से फ़ंक्शन को संशोधित किया।
यदि इस फ़ंक्शन का उपयोग स्ट्रीम 2 के समान नहीं होने पर स्ट्रीम 2 को फिर से लिखने के लिए किया जाता है, तो सभी त्रुटियों की जांच की जानी चाहिए। जब फ़ंक्शन परिणाम सही होता है, तो कुछ भी ठीक है, लेकिन यदि यह गलत है, तो यह जांचना बहुत चालाक होगा कि स्ट्रीम वास्तव में अलग हैं या बस कुछ त्रुटि हुई है।
संपादित: कुछ अतिरिक्त चेक, फ़ाइलेंअरेडेंटिक फ़ंक्शन स्ट्रीम पर आधारित हैंअडेंटिकल और उपयोग उदाहरण।
// Usage example
var lError: Integer;
...
if FilesAreIdentical(lError, 'file1.ext', 'file2.ext')
then Memo1.Lines.Append('Files are identical.')
else case lError of
0: Memo1.Lines.Append('Files are NOT identical!');
1: Memo1.Lines.Append('Files opened, stream read exception raised!');
2: Memo1.Lines.Append('File does not exist!');
3: Memo1.Lines.Append('File open exception raised!');
end; // case
...
// StreamAreIdentical
function StreamsAreIdentical(var aError: Integer;
const aStream1, aStream2: TStream;
const aBlockSize: Integer = 4096): Boolean;
var
lBuffer1: array of byte;
lBuffer2: array of byte;
lBuffer1Readed,
lBuffer2Readed,
lBlockSize: integer;
begin
Result:=False;
aError:=0;
try
if aStream1.Size <> aStream2.Size
then Exit;
aStream1.Position:=0;
aStream2.Position:=0;
if aBlockSize>0
then lBlockSize:=aBlockSize
else lBlockSize:=4096;
SetLength(lBuffer1, lBlockSize);
SetLength(lBuffer2, lBlockSize);
lBuffer1Readed:=1; // just for entering while
while (lBuffer1Readed > 0) and (aStream1.Position < aStream1.Size) do
begin
lBuffer1Readed := aStream1.Read(lBuffer1[0], lBlockSize);
lBuffer2Readed := aStream2.Read(lBuffer2[0], lBlockSize);
if (lBuffer1Readed <> lBuffer2Readed) or ((lBuffer1Readed <> lBlockSize) and (aStream1.Position < aStream1.Size))
then Exit;
if not CompareMem(@lBuffer1[0], @lBuffer2[0], lBuffer1Readed)
then Exit;
end; // while
Result:=True;
except
aError:=1; // stream read exception
end;
end;
// FilesAreIdentical using function StreamsAreIdentical
function FilesAreIdentical(var aError: Integer;
const aFileName1, aFileName2: String;
const aBlockSize: Integer = 4096): Boolean;
var lFileStream1,
lFilestream2: TFileStream;
begin
Result:=False;
try
if not (FileExists(aFileName1) and FileExists(aFileName2))
then begin
aError:=2; // file not found
Exit;
end;
lFileStream1:=nil;
lFileStream2:=nil;
try
lFileStream1:=TfileStream.Create(aFileName1, fmOpenRead or fmShareDenyNone);
lFileStream2:=TFileStream.Create(aFileName2, fmOpenRead or fmShareDenyNone);
result:=StreamsAreIdentical(aError, lFileStream1, lFileStream2, aBlockSize);
finally
if lFileStream2<>nil
then lFileStream2.Free;
if lFileStream1<>nil
then lFileStream1.Free;
end; // finally
except
aError:=3; // file open exception
end; // except
end;
शायद यह आपके लूप को शुरू करने से पहले दोनों स्ट्रीम स्थिति को 0 पर सेट करते समय मदद करता है। –
या पूरी धाराओं को 2 मेमोरीस्ट्रीम में लोड करें और तुलना करने के लिए उन्हें खिलाएं। – Remko
@Uwe Raabe - +1, आप पूरी तरह से सही हैं, @Remko - +1, आप शायद सही भी हैं, मुझे उम्मीद है कि तुलनात्मक समय तुरंत निकलता है जब यह बाइट अंतर –