[erledigt] Dateioperationen (readln, readstrings) und UTF8

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

[erledigt] Dateioperationen (readln, readstrings) und UTF8

Beitrag von Scotty »

Hallo,
wie lese ich Daten mit Umlauten richtig ein?
Ich komme weder bei readln() noch per loadfromfile() oder readstrings() damit zurecht. Vermutlich liegt es daran, dass FPC Strings nicht automatisch als WideStrings behandelt, die Implementierung jeweils aber als String erfolgt (readln(<file>,<widestring>) geht gar nicht). Muss ich nun inifiles.pp neu programmieren? :oops:
Zielplattform soll Windows und Linux sein, ich arbeite unter Ubuntu.
test.txt:

Code: Alles auswählen

[Text]
1=ABC
2=ÄBC
3=ÄÖÜ
4=XYZ
5=äbc
6=xyz
Variante 1:

Code: Alles auswählen

if opendialog1.execute then
begin
  assignfile(tmp,opendialog1.filename);
  reset(tmp);
  memo1.lines.clear;
  while not eof(tmp) do
  begin
    readln(tmp,s);
    memo1.lines.add(s);
  end;
  closefile(tmp);
end;
Variante 2

Code: Alles auswählen

if opendialog1.execute then
with TStringList.Create do
try
  LoadFromFile(OpenDialog1.FileName);
  while Count>0 do
  begin
    Memo1.Lines.Add(Strings[0]);
    Delete(0);
  end;
finally
  Free;
end;
Variante 3

Code: Alles auswählen

if OpenDialog1.Execute then
begin
  sl:=TStringList.Create;
  with TIniFile.Create(OpenDialog1.FileName) do
  try
    ReadSectionValues('Text',sl);
    while sl.Count>0 do
    begin
      Memo1.Lines.Add(sl[0]);
      sl.Delete(0);
    end;
  finally
    Free;
    sl.free;
  end;
end;
Ergebnis:

Code: Alles auswählen

[Text]
1=ABC
4=XYZ
6=xyz
oder mit AnsiToUtf8()

Code: Alles auswählen

[Text]
1=ABC
2=?BC
3=???
4=XYZ
5=?bc
6=xyz
Zuletzt geändert von Scotty am Mi 6. Mai 2009, 17:02, insgesamt 1-mal geändert.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von mschnell »

Scotty hat geschrieben:Hallo,wie lese ich Daten mit Umlauten richtig ein?
readln() und Genossen ist gaaaaaanz alte Technik aus DOS-Zeiten. m.E. sollte man das nicht mit Unicode verheiraten (obwohl es natürlich sicherlich geht).

Wenn Du eine Text-Datei Zeilenweise bearbeiten willst nimmst Du doch besser TStringlist.ReadfromFile.

Und wenn Du Unicode-Widestrings in Lazarus verwenden willst, musst Du Dich sowieso auf einiges gefasst machen. Lies dazu bitte erstmal die entsprechenden tausend Beiträge ein einigen Threads hier. (suchen: "Unicode").

Zuerst musst Du natürlich wissen, wie die Datei, die Du einlesen willst codiert ist (z.B. länderspezifische ANSI, utf8, mit oder ohne Sonder-Kodierungen (ü als zwei separate Codepoints anstatt ein Codepoint aus zwei Code-Bytes), UTF16, mit oder ohne Sonder-Kodierungen ...)

Eine System-Library umprogrammieren würde ich nicht. (da wird sich sowieso in absehbarer Zeit wieder was ändern, wenn der FPC eine flexiblere Unicode-.Unterstützung bekommt. Vermutlich musst Du in Deinem Programm das Einlesen in Widestrings String für String ausprogrammieren.

-Michael
Zuletzt geändert von mschnell am Mo 4. Mai 2009, 15:30, insgesamt 1-mal geändert.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von Scotty »

mschnell hat geschrieben:Lies dazu bitte erstmal die entsprechenden tausend Beiträge ein
Eine Zusammenfassung oder bessere Stichworte wären nett, damit ich Deine Leseaufforderung verstehe. Ich will nichts über die Theorie von WideStrings lesen sondern Dateioperationen insbesondere StringList.LoadFromFile() und Inifile.ReadString() ausführen. Ich habe jedenfalls nichts zu TStringList und UFT8 gefunden.
Edit: In diesem Thread wird die Lösung TMemoryStream plus UTF8Encode diskutiert. Ich will relativ große Textdateien (bis 10MB) einlesen und mag es nicht, wenn der Benutzer nicht sieht, was das Programm gerade macht - deswegen meine "Vorliebe" für readln(). Gibt es ein UTF8IniFile?

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von mschnell »

Scotty hat geschrieben: Ich will nichts über die Theorie von WideStrings lesen
Dann darsft Du keinen Unicode verwenden. (Und da das aktuelle Lazarus immer mit Unicode arbeitet, darfst Du nicht mit Umlauten arbeiten.
Scotty hat geschrieben: Ich habe jedenfalls nichts zu TStringList und UFT8 gefunden.
Da ist auch nichts zu finden. Wenn die Daten UTF8 kodiert sind, ist bleiben sie in TStringlist auch UTF8 kodiert. Wenn Du eine andere Kodierung brauchst, musst Du explizit eine Umkodier-Funktion aufrufen. FPC/Lazarus unterscheidet nicht zwischen unterschiedlich kodierten 8-Bit Strings.
Scotty hat geschrieben: Gibt es ein UTF8IniFile?
Vermutlich nicht. Da gilt dasselbe wie bei TStringList: Wenn die Daten UTF8 kodiert sind, ist bleiben sie auch UTF8 kodiert.

- Michael

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von Scotty »

Vermutlich hast Du recht - ich brauche wohl doch etwas mehr Theorie. Ein paar Schritte habe ich mittlerweile schon gemacht. Vorerst finde ich aber keine Lösung für mein Problem, eine unter Windows erstellte Datei (wahrscheinlich ASCII und nicht ANSI) richtig zu lesen. Es sei denn, ich prüfe jedes Zeichen einzeln. Also formuliere ich meine Frage mal neu:

Wie kann ich Dateien plattformübergreifend lesbar machen?

Und ich spüre schon, dass an der Frage wieder was nicht stimmt :|. So schwierig hatte ich mir den Umstieg von Delphi nicht vorgestellt...

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von Christian »

Das hat nichts mit dem Umstieg von Delphi zu tun sondern eher mit dem Umstieg von ANSI auf Unicode und die Matherie ist nunmal um einiges schwieriger. Sprich du musst schon ein wenig lernwilliger sein als bei ANSI.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6787
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von af0815 »

Scotty hat geschrieben:Wie kann ich Dateien plattformübergreifend lesbar machen?
theo hat darüber schon einiges im Forum hier von sich gegeben und auch Komponenten/Units/Code dazu. Es lohnt sich hier im Forum zu suchen.

Siehe auch Link
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von Scotty »

Den Thread kenne ich und habe mir auch den Code angesehen. Beim genaueren Nachdenken hat mein Problem aber weniger mit Unicode als mit dem OS zu tun. Die Textdatei wird vom Benutzer unter Windows erstellt und lässt sich halt unter Linux nicht so einfach lesen (Stichwort: Codepage). Ich habe testweise die Datei mit Wordpad unter XP als Unicode gespeichert, aber dabei kommt was anderes raus als mit gedit unter Linux. Jetzt habe ich eher ein prinzipielles Problem: weise ich den Benutzer an, ein bestimmtes Format zu nutzen (was ich eigentlich nicht mag, da ein normaler Mensch nicht über UTF nachdenken will, was aber letzten Endes zwingend notwendig ist) oder beschäftige ich mit mit der Frage, warum gedit die Datei richtig einließt und ich das nicht hinbekomme :cry: . Da ich aber auch an vielen anderen Stellen nicht so recht weiter komme, denke ich gerade darüber nach, ob ich nicht wieder zu Delphi zurück gehe.
Dieser Thread hat sich jedenfalls für mich erledigt. Die Quintessenz für mich ist:
Wenn die Daten UTF8 kodiert sind, ist bleiben sie auch UTF8 kodiert.
. Falls jemand anderes ähnliche Schwierigkeiten haben sollte, empfehle ich einen Test mit unter Linux erstellten Dateien.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: [erledigt] Dateioperationen (readln, readstrings) und UTF8

Beitrag von monta »

Ich versteh das Problem nicht ganz.

Ich hab es gerade getestet...du schreibst, du hast große Dateien und musst die Zeilenweise einlesen, damit du Wartebalken usw. anzeigen lassen kannst.

Aber warum? Eine 20MB große Datei ist auf einem Singlecore in deutlich unter 5 Sekunden eingelesen.

Und für alles andere kannst du ja sehr wohl dann die StringList durchgehen, bearbeiten, in Ansi und sonstwas konvertieren und Zeilenweise ins Memo schreiben.

(Ein direktes Memo.LoadFromFiles dauert ca. 25 Sekunden)

Wenn du also schreibst, du hast gerade mal 10 MB große Dateien sollten doch ca. 2 Sekunden zum einlesen drin sein, ohne auf die absoluten LowLevel-Befehle zugreifen zu müssen, die natürlich aus Zeiten jenseits von UTF und Unicode stammen.
Johannes

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Dateioperationen (readln, readstrings) und UTF8

Beitrag von mschnell »

Scotty hat geschrieben:(Stichwort: Codepage).
Dann ist es eben nicht Unicode.
Scotty hat geschrieben:Ich habe testweise die Datei mit Wordpad unter XP als Unicode gespeichert, aber dabei kommt was anderes raus als mit gedit unter Linux.
Dann verwendet andere Programm nicht Unicoode. Unicode ist nicht OS-Abhängig. In der Datei steht aber nicht unbedingt d'rin, dass sie Unicode-kodiert ist und in welcher Weise. Und es gibt jede Menge nicht-Unicode-Programme.
Scotty hat geschrieben:weise ich den Benutzer an, ein bestimmtes Format zu nutzen
Wenn Dein Programm die Datei liest und schreibt (Wenn auch im anderen OS), ist bei voller Unicode-Verarbeitung alles sauber.

-Michael

Antworten