user2858981
user2858981

Reputation: 255

Delphi - Check each line of a file againt another file

I have to check each line of a file against another file. If one line from the first file exists in the second file I have to delete it. Right now i'm using 2 listboxes and the "for listbox1.items.count-1 downto do begin..." My program works but I have to check this for huge files with over 1 milion lines. Is there a faster approach to this method? I want to load the files inside memory in order to be extremely fast! Thanks

Upvotes: 1

Views: 367

Answers (2)

quasoft
quasoft

Reputation: 5438

A quick solution (but not the fastest one) is to use two TStringList lists instead of list boxes.

var
  a, b: TStringList;
  i: Integer;
begin
  a := TStringList.Create;
  b := TStringList.Create;
  try
    a.LoadFromFile('C:\1.txt');
    b.LoadFromFile('C:\2.txt');

    b.Sorted := True;

    for i := a.Count - 1 downto 0 do
    begin
      // Check if line of file 'a' are present in file 'b'
      // and delete line if true

      if b.IndexOf(a[i]) > -1 then
        a.Delete(i);
    end;

    a.SaveToFile('C:\1.txt');
  finally
    b.Free;
    a.Free;
  end;
end;

Again, this is a slow and simple solution that loads whole files in RAM. It still will be much faster than using a ListBox. Sometimes simple is just enough for solving a one-time problem.

A faster method would be to create an index (eg. binary tree) of both files on hard disk and use this index to compare. That way you will not need to store the whole files on disk.

Upvotes: 1

Evgeny
Evgeny

Reputation: 4010

You can use TStringList for this. List for second file should be sorted for faster search. Try this:

var
  l1, l2: TStringList;
  i: integer;
begin
  l1 := nil;
  l2 := nil;
  try
    l1 := TStringList.Create;
    l1.loadfromFile('file1');

    l2 := TStringList.Create;
    l2.LoadFromFile('file2');
    l2.Sorted := True;

    for i := l1.Count -1 downto 0 do
    begin
      if l2.IndexOf(l1[i]) <> -1 then
        l1.Delete(i);
    end;

    l1.SaveToFile('file1');
  finally
    FreeEndNil(l1);
    FreeEndNil(l2);
  end
end

Upvotes: 1

Related Questions