AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi bestimmten Bereich einer Textdatei auslesen

bestimmten Bereich einer Textdatei auslesen

Ein Thema von shadowman · begonnen am 9. Apr 2006 · letzter Beitrag vom 10. Apr 2006
Antwort Antwort
shadowman

Registriert seit: 1. Nov 2005
48 Beiträge
 
#1

bestimmten Bereich einer Textdatei auslesen

  Alt 9. Apr 2006, 19:51
Hallo zusammen,
ich möchte einen bestimmten Bereich (bestimmte Anzahl Zeilen) einer Textdatei in eine StringList einlesen. Ich habe zur verfügung:
Fall 1:
- den Anfang des Bereiches in Bytes
- das Ende des Bereiches in Bytes
- die Länge des Bereiches in Bytes

so wie

Fall 2:
- den Anfang des Bereiches als Zeilennummer
- das Ende des Bereiches als Zeilennummer
- die Länge des Bereiches in Bytes (hier nicht unbedingt nötig vermutlich)


Im Fall 1 müsste man es mit BlockRead machen laut meiner Recherchen, allerdings bekomme ich das nicht hin. Ich bekomme beim Aufruf von BlockRead die Fehlermeldung "E/A-Fehler 998." (Unzulässiger Zugriff auf einen Speicherbereich).

hier der Code:

Delphi-Quellcode:
var
   f: file;
   aktMail: TStringList;
begin
   aktMail := TStringList.Create;
   
   try
      AssignFile(f, <meine Datei>);
      Reset(f,1);
      Seek(f, <der Anfang in Bytes>);
      BlockRead(f, aktMail, <zu lesende Länge>);
    ...
    ...
   finally
      FreeAndNil(aktMail);
   end;
end;
Es gibt viele Fälle im Netz, wo das Thema behandelt wird, aber ich bin daraus leider nicht schlau geworden.
Ist dieser Weg zur Lösung meines Problems überhaupt zu gebrauchen? Wenn ja, würde ich gerne wissen wie das geht.


Im zweiten Fall könnte ich einfach mir ReadLn den Bereich zwischen der Anfangs- und Endzeile einlesen, nur weiß ich nicht, wie ich in der Textdatei zu einer bestimmten Zeile (Anfangszeile) "springen" kann. Seek funktioniert in dem Fall nicht, wenn ich mich nicht irre.

Wie bekomme ich also am besten einen bestimmten Bereich einer Textdatei in eine StringList eingelesen?

Gruß,
shadow
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: bestimmten Bereich einer Textdatei auslesen

  Alt 9. Apr 2006, 20:14
Für Fall 1 ist die Lösung recht einfach:

Delphi-Quellcode:
function LoadStringFromFile(fn: TFileName; iOffset, iSize: Cardinal): String;
begin
  with TFileStream.Create(fn, fmOpenRead) do
  try
    Position := iOffset;
    SetLength(Result, iSize);
    Read(Result[1], iSize);
  finally
    Free;
  end;
end;

var
  s: TStringList;
  iOffset, iSize: Cardinal;
  fn: TFileName;

begin
  s.Text := LoadStringFromFile(fn, iOffset, iSize);
end;
Grüße vom marabu
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#3

Re: bestimmten Bereich einer Textdatei auslesen

  Alt 9. Apr 2006, 21:57
Für Fall 2 gibt es mehrere mögliche Lösungen:

1.) Falls die Datei nicht allzu groß ist, könntest Du sie komplett in eine Stringliste einlesen (Methode LoadFromFile) und anschließend die nicht benötigten Zeilen löschen.
Da dies nur zeilenweise möglich ist, könnte es durch die zahlreichen Stringoperationen schnell zu größeren Laufzeiten kommen.

2.) Alternativ zur Stringliste kannst Du die Datei auch in einen String einlesen (wie in marabus Beispiel). In diesem String suchst Du den n-ten Zeilenvorschub (n = Startzeile - 1). Als Suchfunktion bietet sich z.B. GetPosNumX aus der DP an. Da die Länge des gewünschten Bereichs ja bekannt ist, kannst Du diesen schließlich über die Copy-Funktion extrahieren und der Stringliste zuweisen.

3.) Bei sehr großen Textdateien mußt Du möglicherweise blockweise vorgehen. Dazu wird die Datei als FileStream geöffnet, aus dem immer wieder ein Block (z.B. 16 KByte) in einen Puffer geladen wird. In jedem geladenen Block zählst Du die Zeilenvorschübe. Laden und Zählen wiederholst Du so lange, bis Du den gewünschten Zeilenvorschub gefunden hast; problematisch wird es dabei nur dann, wenn sich der Zeilenvorschub auf zwei Blöcke verteilt. Aus der Fundstelle und der Anzahl der gelesenen Blöcke kannst Du schließlich die absolute Position des Zeilenvorschubs in der Datei errechnen und mit der von marabu beschriebenen Lösung den gewünschten Bereich einlesen.

Für die meisten Dateien dürfte wohl die zweite Lösung die beste sein.

Gruß Hawkeye
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: bestimmten Bereich einer Textdatei auslesen

  Alt 9. Apr 2006, 22:44
Hier noch eine vierte Möglichkeit - solange TextFile noch unterstützt wird - allerdings nur getippt und nicht getestet:

Delphi-Quellcode:
procedure GetLines(fn: TFileName; s: TStrings; iStart, iCount: Cardinal);
const
  BUF_SIZE = 16 shl 10;
var
  tf: TextFile;
  buf: array of Char;
  iLine: Cardinal;
  line: String;
begin
  SetLength(buf, BUF_SIZE);
  AssignFile(tf, fn);
  Reset(tf);
  SetTextBuf(tf, buf[0], BUF_SIZE);
  iLine := 0;
  while not Eof(tf) and (iLine < iStart) do
  begin
    ReadLn(tf);
    Inc(iLine);
  end;
  s.BeginUpdate;
  while not Eof(tf) and (iCount > 0) do
  begin
    ReadLn(tf, line);
    s.Add(line);
    Dec(iCount);
  end;
  s.EndUpdate;
  CloseFile(tf);
end;
Gute Nacht

marabu
  Mit Zitat antworten Zitat
shadowman

Registriert seit: 1. Nov 2005
48 Beiträge
 
#5

Re: bestimmten Bereich einer Textdatei auslesen

  Alt 10. Apr 2006, 14:52
hallo marabu, hallo Hawkeye,

vielen Dank für Eure Hilfe und Tipps.
Habe es jetzt so gemacht wie im ersten Vorschlag von marabu und es funktioniert alles prima.
Danke.

Gruß,
shadow
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf