Autor Beitrag
mathias
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58
Erhaltene Danke: 3



BeitragVerfasst: Di 19.11.13 18:33 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.SaveToFile('äöü.txt');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Lines.LoadFromFile('äöü.txt');
end;

Dies Zeilen funktionieren ohne Probleme.

Im Explorer wird mir diese Datei angezeigt: "äöü.txt"

Woran liegt das ?

Mit Delphi hatte ich dieses Problem nie.

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Di 19.11.13 19:23 
Probier's mal mit UTF8ToAnsi(s). :zwinker:
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.11.13 23:20 
user profile iconmathias hat folgendes geschrieben Zum zitierten Posting springen:
Mit Delphi hatte ich dieses Problem nie.
Delphi ist auch sehr viel weiter entwickelt als Lazarus. Die Stringunterstützung bei Lazarus ist leider weder einheitlich noch durchdacht (UTF8 meistens, aber nicht immer, die Stringoperationen sind wegen UTF8 deutlich langsamer als bei Delphi, automatische Konvertierungen wie mit der Compiler Magic bei Delphi gibt es so nicht, ...).

Wenn man das überall manuell korrigiert, funktioniert es, aber da es nicht einheitlich ist, bleibt oft nur try & error.
mathias Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58
Erhaltene Danke: 3



BeitragVerfasst: Do 21.11.13 00:02 
Danke für den Hinweis mit UTF8, ich konnte mein Programm zu laufen bringen, aber so richtig durch sehe ich nicht.

Ich war immer der Meinung, das ein Zeichen in einem String 8Bit hat, das hat sich wohl unterdessen geändert.
Früher unter DOS war dies so. Unterdessen kann man sogar im Windows Notepad Chinesische Zeichen einfügen.

Ich musste auch feststellen, das TString und TListBox, Zeichenketten unterschiedlich verarbeiten.
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Do 21.11.13 00:43 
Das hast Du schon richtig erkannt. Das hat mit der Unicode-Unterstützung zu tun. So werden z.B. auch chinesische Zeichen unterstützt. Ein Unicode-Zeichen wird in 16 Bit gespeichert. Beim Speichern des Memos wird der Dateiname (warum auch immer) in UTF-8 umgewandelt.

ausblenden Delphi-Quelltext
1:
ShowMessage(UTF8Encode('äöü.txt'))					

... hat den gleichen Effekt.

UTF8ToAnsi(Const S: UTF8String):String; wandelt einfach den in UTF-8 codierten String in Ansi um und umgeht so das Problem.

Viele Grüße
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 21.11.13 07:08 
user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:
Ein Unicode-Zeichen wird in 16 Bit gespeichert. Beim Speichern des Memos wird der Dateiname (warum auch immer) in UTF-8 umgewandelt.
Das stimmt eben gerade nicht. Delphi benutzt 16 Bit pro Unicodezeichen.
Lazarus hingegen benutzt UTF-8, sprich wie viel Byte ein Zeichen braucht ist nicht eindeutig festgelegt, sondern varriiert zwischen einem und vier Byte. Deshalb ist das Stringhandling dort auch komplizierter und langsamer als bei Delphi.

UTF-8 wird unter Betriebssystemen wie Linux oder Mac intern genutzt, anders als bei Windows. Das ist auch der Grund weshalb Lazarus damit arbeitet.

Deshalb wird da nichts beim Speichern in UTF-8 umgewandelt, sondern der Dateiname liegt intern als UTF-8 vor und muss aufgrund der fehlenden automatischen Konvertierung manuell konvertiert werden.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 21.11.13 08:10 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Deshalb wird da nichts beim Speichern in UTF-8 umgewandelt, sondern der Dateiname liegt intern als UTF-8 vor und muss aufgrund der fehlenden automatischen Konvertierung manuell konvertiert werden.
Wobei das an der Stelle ein Bug ist, das sollte nicht so sein.
TFileStream ruft ganz am Ende CreateFile(PChar(string),...) auf, was dann vermutlich CreateFileA ist, dem dann direkt der UTF8-String reingeworfen wird. Kann so nicht gehen.

Wer macht den Bugtracker-Eintrag auf?

Vorher wäre allerdings mal noch zu prüfen, ob String-Literale denn nun eigentlich als UTF8 eincompiliert werden sollten oder nicht.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Do 21.11.13 10:18 
jaenicke hat folgendes geschrieben:
UTF-8 wird unter Betriebssystemen wie Linux oder Mac intern genutzt, anders als bei Windows. Das ist auch der Grund weshalb Lazarus damit arbeitet.

Ach so, ich dachte, Lazarus würde Widestrings mit 16 Bit-Unicode Zeichen nutzen.

Wobei man unbedingt dazusagen muss, dass UTF8ToAnsi nur eine Notlösung ist und mit Unicodezeichen, die nicht im Ansi-Zeichensatz vorkommen, logischerweise nicht funktionieren wird. Mit Umlauten ist das kein Problem, da diese im Ansi-Zeichensatz enthalten sind.
mathias Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58
Erhaltene Danke: 3



BeitragVerfasst: Do 21.11.13 19:05 
Habe ich das jetzt richtig verstanden ?

Ein ANSI-String besteht auch 8 Bit, ein UTF8-String kann 8,16,24 oder 32 bestehen.

In meinem Programm war der Fehler in FindFirst, mit FindFirstUTF8 hat es geklappt.
Bei jpeg.SaveToFile, musst ich das UTF8toANSI entfernen.

Bei den Memo1.Lines.SaveToFile('äöü.txt') im obersten Beitrag braucht es das UTF8toANSI.

Momentan sehe ich da nicht mehr durch.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 21.11.13 21:25 
user profile iconmathias hat folgendes geschrieben Zum zitierten Posting springen:
Momentan sehe ich da nicht mehr durch.
Das geht nicht nur dir so...
Meine Strategie ist an der Stelle auch Trial&Error bei Lazarus, wenn ich mal damit etwas machen muss. Nach Logik suchen kostet nur Zeit. ;-)
mathias Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58
Erhaltene Danke: 3



BeitragVerfasst: Fr 22.11.13 19:52 
Unterdessen bin ich weiter gekommen, SaveTofile ist nicht gleich SaveToFile.

Beim speichern einer Memo muss ich UTF8ToAnsi schreiben, bei einer Bitmap braucht es die Umwandlung nicht.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  Bitmap.SaveToFile('öüä.bmp'); // funktioniert
  Bitmap.SaveToFile(UTF8ToAnsi('öüä.bmp')); // Kommt Fehlermeldung


  Memo1.Lines.SaveToFile('äöü.txt'); // Es werden Hieroglyphen erzeugt
  Memo1.Lines.SaveToFile(UTF8ToAnsi('äöü.txt')); // funktioniert

Im Lazarus Quellcode steht folgendes.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
Procedure TStrings.SaveToFile(const FileName: string);

Var TheStream : TFileStream;

begin
  TheStream:=TFileStream.Create(FileName,fmCreate);
  try
    SaveToStream(TheStream);
  finally
    TheStream.Free;
  end;
end;    

procedure TGraphic.SaveToFile(const Filename: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(UTF8ToSys(Filename), fmCreate);
  try
    SaveToStream(Stream);
  finally
    Stream.Free;
  end;
end;


Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt