![]() |
File compare
Hi Leutz
Ich weiß es gibt schon einige Threads darüber aber ich habe noch keine brauchbare Lösung gefunden. Ich will praktisch 2 Files miteinander vergleichen und sobald sich die eine von der anderen in irgendeiner Art und Weise unterscheidet (Inhaltlich) reagieren? Wie könnte das realisiert werden? LG |
AW: File compare
Eine Möglichkeit: beide Dateien in jeweils einen Stream einlesen und beide Streams mit CompareMem vergleichen.
|
AW: File compare
dh mit:
Delphi-Quellcode:
auslesen und dann zB mit folgender funktion vergleichen:
Stream := TFileStream.Create('c:\Temp\StreamTest.Datei', fmOpenRead);
Delphi-Quellcode:
?
function CompareMem(P1, P2: PChar; Length: Integer): Boolean;
begin Result := False; while Length > 0 do if P1^ = P2^ then begin Dec(Length); Inc(P1); Inc(P2); end else Exit; Result := True; end; LG |
AW: File compare
Erstelle von beiden Dateien eine Hash und vergleiche diesen.
|
AW: File compare
Thread:
![]() Ergebnis: ![]() Funzt ganz gut. :-D |
AW: File compare
@ Lucki
mit der MD5.pas zB aus ![]() ich nehme mal an ich muss MDFile aufrufen und anschließend MD5Match? Leider noch nicht mit sowas zu tun gehabt ! LG |
AW: File compare
Ungetestet:
Delphi-Quellcode:
function FilesAreEqal(const First, Second: TFilename): Boolean;
var FirstStream, SecondStream: TMemoryStream; begin Result := FileExists(First) and FileExists(Second); if Result then begin FirstStream := TMemoryStream.Create; try SecondStream := TMemoryStream.Create; try FirstStream.LoadFromFile(First); SecondStream.LoadFromFile(Second); Result := FirstStream.Size = SecondStream.Size; if Result then begin FirstStream.Position := 0; SecondStream.Position := 0; Result := CompareMem(FirstStream.Memory, SecondStream.Memory); end; finally SecondStream.Free; end; finally FirstStream.Free; end; end; end; |
AW: File compare
Für die ganz schnellen, erst die Größe der beiden Dateien vergleichen!
Gruß K-H |
AW: File compare
@DeddyH:
Dann lade mal bitte zwei 20GB große Dateien in den Arbeitsspeicher :P PS: Hashen lohnt sich eig. erst, wenn man mehrere Dateien mit einer vergleichen will. |
AW: File compare
ich mache es jetzt mit der FileCompare unit!
Funktioniert perfekt! danke! |
AW: File compare
Zitat:
|
AW: File compare
Kann ich auch irgendwie herausfinden, was genau sich geändert hat? zB die betroffene Zeile?
LG |
AW: File compare
Geht es nur um Textdateien? Ansonsten gibt es ja keine Zeilen.
|
AW: File compare
^jap ich vergleiche praktisch 2 textdateien!
LG |
AW: File compare
Die kannst Du doch einfach zeilenweise einlesen und vergleichen.
|
AW: File compare
Nur mal noch bezüglich Gleichheitsprüfung:
Vorausgesetzt, die Texdateien sind nicht zu groß, könnte man sie einfach in 2 TStringList laden und auf
Delphi-Quellcode:
prüfen. Zumindest wäre das ein recht unkomplizierter Weg.
SL1.Text = SL2.Text
|
AW: File compare
Damit bekommst aber keine Zeilennummer bei evtl. Unterschieden ;)
|
AW: File compare
so in etwa?
ich mein sieht grauslich aus aber wäre das prinzip richtig?
Delphi-Quellcode:
i := 0;
i2 := 0; countsum := getlinecount('C:\myfile.txt'); sl := TStringlist.Create; sl2 := TStringlist.Create; sl.loadfromfile('C:\myfile.txt'); sl2.loadfromfile('C:\my2ndFile.txt'); while i < countsum do begin i := i + 1; i2 := i2 + 1; if sl[i] = sl[i2] then writeln('Kein Unterschied'); end; ... |
AW: File compare
Ungetestet:
Delphi-Quellcode:
function FilesEqual(const First, Second: TFilename; out DiffLine: integer): Boolean;
var s1, s2: TStringlist; i: integer; begin Result := FileExists(First) and FileExists(Second); if Result then begin s1 := TStringlist.Create; try s1.LoadFromFile(First); s2 := TStringlist.Create; try s2.LoadFromFile(Second); i := 0; while (i < s1.Count) and (i < s2.Count) do begin Result := s1[i] = s2[i]; if not Result then begin DiffLine := i; i := s1.Count; end; inc(i); end; finally s2.Free; end; finally s1.Free; end; end; end; |
AW: File compare
Delphi-Quellcode:
Result := FileExists(First) and FileExists(Second);
if Result then begin s1 := TStringlist.Create; try s2 := TStringlist.Create; try s1.LoadFromFile(First); s2.LoadFromFile(Second); Result := s1.Count = s2.Count if Result then begin i := 0; while (i < s1.Count) and (i < s2.Count) do begin Result := s1[i] = s2[i]; if not Result then begin DiffLine := i; Break; end; inc(i); end; end else DiffLine := Min(s1.Count, s2.Count); finally s2.Free; end; finally s1.Free; end; end; |
AW: File compare
was passiert aber wenn mehrere lines nicht gleich sind.. result ist doch immer nur 1 Wert?
|
AW: File compare
Klar, die erste unterschiedliche Zeile. Ansonsten musst Du es halt so umbauen/erweitern, dass eine Liste hinten rauskommt.
|
AW: File compare
hm habe folgende function:
Delphi-Quellcode:
und rufe das auf:
function FilesEqual(const First, Second: TFilename; out DiffLine: integer): Boolean;
var s1, s2: TStringlist; i: integer; begin Result := FileExists(First) and FileExists(Second); if Result then begin s1 := TStringlist.Create; try s1.LoadFromFile(First); s2 := TStringlist.Create; try s2.LoadFromFile(Second); i := 0; while (i < s1.Count) and (i < s2.Count) do begin Result := s1[i] = s2[i]; if not Result then begin DiffLine := i; i := s1.Count; s3.Add(s1[i]); end; inc(i); end; finally s2.Free; end; finally s1.Free; end; end; end;
Delphi-Quellcode:
bekomme aber permanent folgendes:
test_functions.FilesEqual('C:\software.txt','C:\software2.txt',i);
i2 := 0; for i2 := 0 to vlxsysstate_functions.s3.Count -1 do Writeln(s3[i2]); test_functions.s3.Free; EStringListError: Listenindex ³berschreitet das Maximum (166) was ist da falsch? |
AW: File compare
Wo kommt denn das s3 in der Funktion jetzt her?
|
AW: File compare
und in welcher Zeile tritt der Fehler auf?
Gruß K-H und das ist doch nicht Dein Ernst oder?
Delphi-Quellcode:
begin
DiffLine := i; i := s1.Count; s3.Add(s1[i]); end; |
AW: File compare
s3 ist in meiner test_functions unit deklariert
welche zeile kann ich leider nicht sagen da er sich beim debug bei folgendem aufruf:
Delphi-Quellcode:
verabschiedet...
test_functions.FilesEqual('C:\software.txt','C:\software2.txt',i);
Wieso was ist daran so schlimm? LG |
AW: File compare
Ich habe das ungute Gefühl, dass Du nicht genau weißt, was Du da tust.
[edit] i steht auf Anzahl der Listenelemente, anschließend willst Du diesen nicht existenten Eintrag dann an s3 anhängen. Wie soll das funktionieren? [/edit] |
AW: File compare
Zum einen, empfehle ich das Debuggen mit Hilfe von [F7], zum anderen ist
Delphi-Quellcode:
tödlich.
i:=s1.count;
s3.add(s1[i]); Gruß K-H |
AW: File compare
Und übergib s3 als Parameter, das ist ja gruselig so.
|
AW: File compare
Zitat:
Gruß K-H |
AW: File compare
Also nochmal aufgebohrt (aber immer noch nicht getestet^^):
Delphi-Quellcode:
function FilesEqual(const First, Second: TFilename; DiffList: TStrings): Boolean;
var s1, s2: TStringlist; i: integer; begin Assert(Assigned(DiffList)); Result := FileExists(First) and FileExists(Second); if Result then begin DiffList.BeginUpdate; try DiffList.Clear; s1 := TStringlist.Create; try s1.LoadFromFile(First); s2 := TStringlist.Create; try s2.LoadFromFile(Second); i := 0; while (i < s1.Count) and (i < s2.Count) do begin if s1[i] <> s2[i] then DiffList.AddObject(s1[i], TObject(i)); inc(i); end; finally s2.Free; end; finally s1.Free; end; finally DiffList.EndUpdate; end; Result := DiffList.Count = 0; end; end; |
AW: File compare
OK, bin halt eher unskilled, habs jetzt aber, zumindest funktionierts :)
Delphi-Quellcode:
aufruf:
function test(const First, Second: TFilename; out stringL: TStringlist): Boolean;
var s1, s2: TStringlist; i: integer; begin Result := FileExists(First) and FileExists(Second); if Result then begin s1 := TStringlist.Create; try s1.LoadFromFile(First); s2 := TStringlist.Create; try s2.LoadFromFile(Second); i := 0; while (i < s1.Count) and (i < s2.Count) do begin Result := s1[i] = s2[i]; if not Result then begin stringL.Add(s1[i]); //i := s1.Count; end; inc(i); end; finally s2.Free; end; finally s1.Free; end; end; end;
Delphi-Quellcode:
Könnte man hier etwas aussetzen ?
try
sl := TStringlist.Create; test_functions.test('C:\software.txt','C:\software2.txt',sl); Writeln(sl.Text); finally sl.Free; end; LG |
AW: File compare
Zitat:
|
AW: File compare
Da Deine Funktion nach dem ersten bemerkten Unterschied aussteigt, kannst Du auch auf die Stringliste verzichten und gleich einen String als Var-Parameter übergeben. Und ein Objekt als out-Paramter ist nicht das Wahre. Willst Du alle Unterschiede (zumindest die, die innerhalb der minimalen Zeilenanzahl beider Dateien liegen) auflisten, schau Dir einmal meine letzte Version an, die speichert auch die Zeilennummer mit (wenn auch etwas versteckt als TObject).
|
AW: File compare
Als Advocatus Diaboli ein Einwurf zum Nachdenken. Nicht an DeddyH's Lösung, sondern an das, was man erreichen will:
Wenn du 1000 Zeilen hast, in einer Datei aber eine neue Zeile an z.B. Stelle 3 eingefügt wurde, dann sind die Dateien bis auf diese eine Zeile gleich, du bekommst aber 997 Fehler. |
AW: File compare
Daran hatte ich auch schon gedacht, aber wie will man das verhindern?
[edit] Abgesehen davon kann das ja auch richtig sein, je nachdem, was man beabsichtigt. [/edit] |
AW: File compare
Ins unreine gedacht,
für jede Zeile einen Hash-wert erstellen und gleiche Zeilen/Hash-werte aus dem Topf entfernen. Was übrig bleibt ist nicht gleich. Gruß K-H |
AW: File compare
[edit]Bezieht sich auf #36, war zu lahm[/edit]
Kannste nicht verhindern. Man kann jetzt die Fuzzy-Pistole rausholen und Ähnlichkeitsanalysen machen usw. aber wie du schon sagst: Es hängt davon ab, was man damit machen will und vllt. ist es genauso schon beabsichtigt. |
AW: File compare
hm ihr habt recht... Die Idee von mir ist momentan zerstört :)
Der Plan war eigentlich mir alle installierten programme und windows patches auszulesen. Diese speichere ich in ein Textfile. anschließend starte ich das Programm neu und lese mir die programme erneut ein, dann werden die frisch eingelesenen mit dem vorhin abgelegten file verglichen. Sollte sich etwas geändert haben reagiere ich dementsprechend... Das File ändert sich NIE, habe dazu einen Pararmeter eingebaut der die Liste bei bedarf neu erstellt. Wie könnte ich das realisieren? Die Funktion zum auslesen der Programme über die Registry funktioniert eigentlich prima aber die compare geschichte zerbricht mir den Kopf! LG |
AW: File compare
Hallo value is NULL,
wenn's nur um den Abgleich zweier Listen geht, dann gehe doch einfach die zweite Liste durch und prüfe mit Liste1.IndexOf ab, ob der jeweilige Eintrag dort drin ist. Ggfs. das Gleiche andersrum (Liste1 gegen Liste 2), um gelöschte Einträge zu finden. Gruß blauweiss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz