0

コレクションに画像ファイル名を追加する、開発中の実験的なアプリがあります。別のコレクションに存在するファイルを除いて、コレクション内のすべてのファイルを削除する最も効率的な方法を見つけようとしています。ファイルはどのコレクションにも存在できます。

次のフィールドを持つ TClientDataSet があります。

ClientDataSet1.FieldDefs.Add('Index', ftInteger);
ClientDataSet1.FieldDefs.Add('Collection', ftString, 50);
ClientDataSet1.FieldDefs.Add('Filename', ftString, 254);

I came up with this which seems to work but seems inefficient:
var
  i: Integer;
  j: Integer;
  iCollectionToDelete: string;
  iCollection: string;
  iFilename: string;
  iFilenameInOtherCollection: string;
  iFilesInOtherCollectionsStringList: TStringList;
begin
  iCollectionToDelete := ListBox1.Items[ListBox1.ItemIndex];
  { Set filtered to false to see all the records in the database }
  ClientDataSet1.Filtered := False;
  { Create a list of files not in the collection to be deleted }
  iFilesInOtherCollectionsStringList := TStringList.Create;
  try
    for i := 0 to ClientDataSet1.RecordCount - 1 do
    begin
       iCollection := ClientDataSet1.FieldByName('Collection').AsString;
       iFilename := ClientDataSet1.FieldByName('Filename').AsString;
       if iCollection <> iCollectionToDelete then
       begin
          iFilenameInOtherCollection := ClientDataSet1.FieldByName('Filename').AsString;
          iFilesInOtherCollectionsStringList.Add(iFilename);
       end;
       ClientDataSet1.Next;
    end;

    { Compare the iFilenameInOtherCollection with all the filenames in the
      dataset and if the iFilename is not in the other collection then
      erase the file }
    ClientDataSet1.First;
    for i := 0 to ClientDataSet1.RecordCount - 1 do
    begin
       iFilename := ClientDataSet1.FieldByName('Filename').AsString;
       ClientDataSet1.Next;
       for j := 0 to iFilesInOtherCollectionsStringList.Count - 1 do
       begin
          iFilenameInOtherCollection := iFilesInOtherCollectionsStringList[j];
          if iFilesInOtherCollectionsStringList.IndexOf(iFilename) = -1 then
            if FileExists(iFilename) then
             WindowsErase(handle, iFilename, False, False, False, False);
       end;
    end;
  finally
    iFilesInOtherCollectionsStringList.Free;
  end;
end;

私の質問は、これをより効率的にすることはできますか、それとも TClientDataset メソッドだけを使用して同じことを行う方法はありますか?

4

2 に答える 2

1

iFilesInOtherCollectionsStringList.Sorted := True埋めたら追加するだけ。IndexOf次に、非常に遅い 1 つずつループする代わりに、高速なバイナリ検索を使用します。おそらく、それはあなたの目的には十分でしょう。

もう 1 つのオプションは、最初に削除するリストを準備してから、バックグラウンドで削除を実行するワーカー スレッドを起動することです。通常、ファイル操作はメモリ比較よりもはるかに遅いため、これが役立つ可能性があります。行をコメントアウトすることで、削除がプロセスの速度を低下させているかどうかを確認できますWindowsErase

于 2014-10-28T16:46:52.537 に答える