Einzelnen Beitrag anzeigen

Benutzerbild von stoxx
stoxx

Registriert seit: 13. Aug 2003
1.111 Beiträge
 
#2

Re: riesen problem mit großer xml datei

  Alt 21. Jul 2006, 04:51
wenn Du die Datei lesen möchtest, und Dir eine einfache Ansicht als Textdatei und nicht als XML Datei genügt, dann solltest Du das selber programmieren, mit einer einfachen Memo und die Datai quasi "online" lesen. Also nicht vollständig in den Speicher laden, sondern in Abhängigkeit von der Position des Scrollbalkens die entsprechenden Zeilen lesen, die Du zur aktuellen Ansicht benötigst.
Wenn Du XML Features benötigst, dass auch Knoten erstellt werden die Du dann in einem Treeview benutzen möchtest, wirds wahrscheinlich schwer !
Aber nun zum simplen Anzeigen per TextEditor (TMemo)

Wenn Du also die Datei "online" liest, kannst Du von den 2 GB jede Zeile ansteuern.

Folgender Code von hier: http://www.swissdelphicenter.ch/de/showcode.php?id=1628
könnte Dir dabei helfen.
Wenn der Scrollbalken sich also in der Mitte befindet, liest Du nur Zeile 10.000 bis 10.020 oder so.
Damit das ganze überhaupt schnell funktioniert MUSST Du einen Index über die Datei bilden.
(Du kannst Dich ja nicht jedesmal z.b. 1,5 GB von vorn durch die Datei hangeln, das wäre Blödsinn)
Also für jeden Anfang einer neuen Zeile musst Du die Byteposition in der Datei in einem Index gespeichert haben. (Datei einmal durchgehen um den Index zu erstellen)
Mit diesem Index findest Du also recht flott heraus, an welcher Byteposition Deine x-te Zeile in Deiner Textdatei beginnt.
Wenn Du dann noch binäre Such Algorithmen implementierst, sollte das alles so flott gehen, wie als würdest Du eine 50 kb große Textdatei anzeigen.
Und wenn Du fleißig suchst, gibts vielleicht so ein Programm schon im Netz

Gruß stoxx



Delphi-Quellcode:
function GrabLine(const AFileName: string; ALine: Integer): string;
var
  fs: TFileStream;
  buf: packed array[0..4095] of Char;
  bufRead: Integer;
  bufPos: PChar;
  lineStart: PChar;
  tmp: string;
begin
  fs := TFileStream.Create(AFileName, fmOpenRead);
  try
    Dec(ALine);
    bufRead := 0;
    bufPos := nil;

    { read the first line specially }
    if ALine = 0 then
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      if bufRead = 0 then
        raise Exception.Create('Line not found');
      bufPos := buf;
    end else
      while ALine > 0 do
      begin
        { read in a buffer }
        bufRead := fs.Read(buf, SizeOf(buf));
        if bufRead = 0 then
          raise Exception.Create('Line not found');
        bufPos := buf;
        while (bufRead > 0) and (ALine > 0) do
        begin
          if bufPos^ = #10 then
            Dec(ALine);
          Inc(bufPos);
          Dec(bufRead);
        end;
      end;
    { Found the beginning of the line at bufPos... scan for end.
      2 cases:
        1) we'll find it before the end of this buffer
        2) it'll go beyond this buffer and into n more buffers }

    lineStart := bufPos;
    while (bufRead > 0) and (bufPos^ <> #10) do
    begin
      Inc(bufPos);
      Dec(bufRead);
    end;
    { if bufRead is positive, we'll have found the end and we can leave. }
    SetString(Result, lineStart, bufPos - lineStart);
    { determine if there are more buffers to process }
    while bufRead = 0 do
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      lineStart := buf;
      bufPos := buf;
      while (bufRead > 0) and (bufPos^ <> #10) do
      begin
        Inc(bufPos);
        Dec(bufRead);
      end;
      SetString(tmp, lineStart, bufPos - lineStart);
      Result := Result + tmp;
    end;
  finally
    fs.Free;
  end;
end;
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.
  Mit Zitat antworten Zitat