Einzelnen Beitrag anzeigen

Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#19

Re: FileQuickSort (Dateien mit wenig Speicherlast sortieren)

  Alt 15. Mär 2009, 08:09
So also hier mal mein Versuch, das in eine Klasse zu packen:

Interface Teil:
Delphi-Quellcode:
uses SysUtils, Classes;

resourcestring
  txt_SourceFileError = 'Quell-Datei kann nicht geöffnet werden!';
  txt_TargetFileError = 'Ziel-Datei kann nicht geöffnet werden!';

type
  EFileSorterOpenError = class(Exception);

  TLineIndex = record
    offset,
    size : Integer;
    prefetch : AnsiString;
  end;
  TFileIndex = array of TLineIndex;

  TTextFileSorterStatus = (tfsIndexing, tfsSorting, tfsWriting, tfsDone);
  TGetLineTyp = (glt_File, glt_FileUpper, glt_Prefetch);

  TSortNotifyEvent = procedure (Sender : TObject; Status : TTextFileSorterStatus;
                                PercentDone : Integer; var Cancel : Boolean) of object;

  TTextFileSorter = class
  private
    FInFileStream : TFileStream;
    FLastPromille : Integer;
    FCancelSort : Boolean;
    FFileIndex : TFileIndex;
    FFileIndexBlock : Integer;
    FPrefetchSize : Integer;
    FSourceFilename: String;
    FDestinationFilename: String;
    FOnSorting: TSortNotifyEvent;
    procedure SetPrefetchSize(const Value : Integer);
    procedure SetDestinationFilename(const Value: String);
    procedure SetOnSorting(const Value: TSortNotifyEvent);
    procedure SetSourceFilename(const Value: String);
  protected
    procedure LoadIndex;
    function LineFromFile(Row : Integer): AnsiString;
    function GetIndexLine(Row : Integer; LineTyp : TGetLineTyp): AnsiString;
    function CompareLinesExact(Row1, Row2 : Integer) : Integer;
    procedure SortIndex(LoIndex, HiIndex: Integer);
    procedure WriteTargetFile;
  public
    constructor Create(aSourceFile, aDestFile : String);
    destructor Destroy; override;
    procedure Sort;
    property PrefetchSize : Integer read FPrefetchSize write SetPrefetchSize;
    property SourceFilename : String read FSourceFilename write SetSourceFilename;
    property DestinationFilename : String read FDestinationFilename write SetDestinationFilename;
    property OnSorting : TSortNotifyEvent read FOnSorting write SetOnSorting;
  end;
...und ein Beispiel für die Nutzung:
Delphi-Quellcode:
procedure TFormFileSort.SortNotifyEvent(Sender : TObject; Status : TTextFileSorterStatus;
                                        PercentDone : Integer; var Cancel : Boolean);
resourcestring
  txt_StatusIndex = 'Index wird aufgebaut...';
  txt_StatusSort = 'Sortiere Datei (%d%%)';
  txt_StatusWrite = 'Schreibe Ziel-Datei...';
  txt_StatusDone = 'Fertig.';
begin
  ProgressBar1.Position := PercentDone;
  case Status of
    tfsIndexing : GroupBoxWork.Caption := txt_StatusIndex;
    tfsSorting : GroupBoxWork.Caption := Format(txt_StatusSort,[PercentDone]);
    tfsWriting : GroupBoxWork.Caption := txt_StatusWrite;
    tfsDone : GroupBoxWork.Caption := txt_StatusDone;
  end;
  Application.ProcessMessages;
end;

procedure TFormFileSort.Button1Click(Sender: TObject);
var
  TextFileSorter : TTextFileSorter;
begin
  TextFileSorter := TTextFileSorter.Create(EditSource.Text,EditTarget.Text);
  try
    TextFileSorter.OnSorting := SortNotifyEvent;
    TextFileSorter.PrefetchSize := SpinEditPrefetch.Value;
    TextFileSorter.Sort;
  finally
    TextFileSorter.Free;
  end;
end;
Die komplette Unit mit der Klasse liegt in der Anlage.

Wahrscheinlich sind noch Anfänger-Fehler drin, da ich mit der Verwendung von Klassen nur wenig bis gar keine Ahnung hab'. Mir sind auch ein paar Fragen gekommen:

Die Verteilung der Variablen und Methoden ist so richtig (private, protected)?
Methoden greifen auf Variablen innerhalb der Klasse zu, damit nicht unabhängig, trotzdem OK?
Class TList (Delphi Source) lagert QuickSort in eine lokale Funktion der Unit aus, warum?
Eigene Exeption sinnvoll, wenn FileOpen ein Standard-Fehler ist?

***

Es ist wohl sinnvoll es aus der Code-Library raus zu nehmen und passend zu verschieben. Ich ändere den Titel dann in etwa wie folgt um. "Von Standard-Code zu einer Klasse" (<- oder bitte vom verschiebenden Moderator gleich passen zu ändern). Danke!
Angehängte Dateien
Dateityp: 7z utextfilesorter_189.7z (2,3 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat