[Gelöst] File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 10:35

Ich brauche mal eure Meinung, bevor ich das zu voreilig an Microsoft weiter gebe.

Und zwar nutze den Encoding-Parameter von File.CREATE, um den Zeichensatz der Datei in UTF-8 vorzugeben. Beispiel:
Code:
TestFile.TEXTMODE := TRUE;
TestFile.WRITEMODE := TRUE;

TestFile.CREATE('C:\Temp\UTF8\Test.txt',TEXTENCODING::UTF8);
TestFile.WRITE(meinText); // siehe Kommentar unten
TestFile.CLOSE


Zum Schluss öffne ich die erstellte Datei im Texteditor, um mittels "Speichern unter" den verwendeten Zeichensatz zu kontrollieren.
Dabei stellt sich nun folgendes heraus:
  • Ist Variable meinText leer oder enthält nur "einfache" Buchstaben wie "abc", dann wird die Datei mit Encoding = ANSI !!! abgespeichert
  • Nur wenn meinText Umlaute o.ä. enthält, wird sie auch mit Encoding = UTF-8 abgelegt.

Wiederhole ich den Test mittels DotNet-Variablen (das Encoding hängt dann nicht am File.OPEN, sondern an der DotNet streamWriter-Variablen; Codebeispiel siehe hier), dann wird die Datei in jedem Fall als UTF-8 abgespeichert.
Genau so hätte ich das auch bei File.CREATE erwartet ... Was meint ihr?

Onlinehilfe hat geschrieben:Optionally, you can specify the encoding on the file. By specifying the text encoding, you ensure that all the language-specific characters are represented correctly in Microsoft Dynamics NAV when you read data and write data.




PS: Habe den Test mit ASCII und ANSII als Vorgabe versucht.
  • ANSI = encoding.GetEncoding(1252): Die Datei wird immer (sowohl mit NAV- als auch DotNetFunktion) im ANSI-Format erstellt
  • ASCII = encoding.GetEncoding(850): Die Datei wird immer im ANSI-Format erstellt ....!!
Was habe ich hier nicht verstanden ....?!

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:02

Natalie hat geschrieben:Ist Variable meinText leer oder enthält nur "einfache" Buchstaben wie "abc", dann wird die Datei mit Encoding = ANSI !!! abgespeichert

Kann ich nicht bestätigen, meine erzeugte Datei mit Inhalt "abede" zeigt Notepad++ korrekt als UTF-8 an. (mit Build 44365)

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:06

Kowa hat geschrieben:Kann ich nicht bestätigen, meine erzeugte Datei mit Inhalt "abede" zeigt Notepad++ korrekt als UTF-8 an. (mit Build 44365)

Nimm mal bitte den Standard-Editor, nur um sicher zu gehen. Mein Build ist übrigens CU6 (45480). Wenns am Ende eine Macke vom Editor ist, soll es mir recht sein ...

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:13

Hallo Natalie,

ich bekomme mit dem StreamWriter exakt das gleiche Ergebnis wie du unter Dynamics NAV 2015 (Build 8.00.45483):

Code:
Customer1.GET('10000');
Customer2.GET('30000');

TestFile.TEXTMODE := TRUE;
TestFile.WRITEMODE := TRUE;
TestFile.CREATE('C:\Temp\UTF8_Test1.txt', TEXTENCODING::UTF8);
TestFile.WRITE(Customer1.Name);
TestFile.CLOSE;

TestFile.TEXTMODE := TRUE;
TestFile.WRITEMODE := TRUE;
TestFile.CREATE('C:\Temp\UTF8_Test2.txt', TEXTENCODING::UTF8);
TestFile.WRITE(Customer2.Name);
TestFile.CLOSE;

TestFile.TEXTMODE := TRUE;
TestFile.WRITEMODE := TRUE;
TestFile.CREATE('C:\Temp\UTF16_Test1.txt', TEXTENCODING::UTF16);
TestFile.WRITE(Customer1.Name);
TestFile.CLOSE;

TestFile.TEXTMODE := TRUE;
TestFile.WRITEMODE := TRUE;
TestFile.CREATE('C:\Temp\UTF16_Test2.txt', TEXTENCODING::UTF16);
TestFile.WRITE(Customer2.Name);
TestFile.CLOSE;

TestFile.CREATE('C:\Temp\UTF8_Test3.txt');
TestFile.CREATEOUTSTREAM(OStream);
StreamWriter := StreamWriter.StreamWriter(OStream);
StreamWriter.WriteLine(Customer2.Name);
StreamWriter.Close();
TestFile.CLOSE;


TestFile.CREATE('C:\Temp\UTF8_Test4.txt');
TestFile.CREATEOUTSTREAM(OStream);
StreamWriter := StreamWriter.StreamWriter(OStream, Encoding.UTF8);
StreamWriter.WriteLine(Customer2.Name);
StreamWriter.Close();
TestFile.CLOSE;


Unterschied ist allein die Byte Order Mark im zweiten Fall mit .NET (Test4):
Code:
00000000h: 47 69 6C 64 65 20 4A 75 70 69 74 65 72 20 56 65 72 73 69 63 68 65 72 75 6E 67 73 20 41 47 0D 0A ; Gilde Jupiter Versicherungs AG..
00000000h: EF BB BF 47 69 6C 64 65 20 4A 75 70 69 74 65 72 20 56 65 72 73 69 63 68 65 72 75 6E 67 73 20 41 47 0D 0A ; Gilde Jupiter Versicherungs AG..


Die ist aber nicht zwingend notwendig und wenn gelöscht, siehst du die identischen Ergebnisse:
Code:
00000000h: 47 69 6C 64 65 20 4A 75 70 69 74 65 72 20 56 65 72 73 69 63 68 65 72 75 6E 67 73 20 41 47 0D 0A ; Gilde Jupiter Versicherungs AG..
00000000h: 47 69 6C 64 65 20 4A 75 70 69 74 65 72 20 56 65 72 73 69 63 68 65 72 75 6E 67 73 20 41 47 0D 0A ; Gilde Jupiter Versicherungs AG..


Letztendlich ist eine UTF-8 Datei eine ANSI-Datei, solange keine Unicode-Zeichen vorkommen (und nicht explizit eine BOM existiert).

Ich würde behaupten es ist korrekt. Ein Auszug aus dem StreamWriter Constructor ohne Angabe eines Encodings:
This constructor creates a StreamWriter with UTF-8 encoding without a Byte-Order Mark (BOM), so its GetPreamble method returns an empty byte array.

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:20

Danke ... Ergibt der ASCII-Test damit für dich ebenfalls Sinn?
PS: Habe den Test mit ASCII und ANSII als Vorgabe versucht.
  • ANSI = encoding.GetEncoding(1252): Die Datei wird immer (sowohl mit NAV- als auch DotNetFunktion) im ANSI-Format erstellt
  • ASCII = encoding.GetEncoding(850): Die Datei wird immer im ANSI-Format erstellt ....!!

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:38

Natalie hat geschrieben:Danke ... Ergibt der ASCII-Test damit für dich ebenfalls Sinn?
ASCII und ANSI sind nur zwei Kodierungen. ASCII, uralt, nimmt für die Zeichencodierung 7 Bit her, ANSI 8 Bit.
Ich denke es wird heute nicht mehr unterschieden, ob das achte Bit genutzt wird oder nicht.

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:43

Jetzt habe ich das auch. Entweder hatte ich ein Cacheproblem, oder Notepad++ zeigt falsch an :roll: .

Verifizieren lässt sich das nur über die Byte Order mark (BOM) am Dateianfang.
Die gibt es nur bei Unicode-Dateien, bei ANSI fehlt diese. Kontrollieren kann man das mit einem Hexeditor.
Korrekte UTF-8 mit BOM EF BB BF.
UTF8.png

UTF-8 aus NAV ohne die BOM.
NAVUTF.png
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 11:48

OK, danke euch beiden.

Re: File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 12:23

SilverX hat geschrieben:Ich denke es wird heute nicht mehr unterschieden, ob das achte Bit genutzt wird oder nicht.

Unterschiedliche Codepages haben die schon, auch die Urversion kommt noch im .NET als Default hoch.
Die 7-Bit Urversion (US-ASCII) hat später die Codepage 20127 bekommen.
Die daraus entstandene 8-Bit Version Codepage 437 (in USA) war dann nur eine von vielen "Extended ASCII"-Codepages, in Westeuropa war dann CP 850 im Einsatz.

Code Page Identifiers

ASCII, uralt,

Mein Jahrgang :mrgreen: .

Re: [Gelöst] File.CREATE in UTF-8 wird zu ANSI

13. Mai 2016 14:25

  1. Die BOM (Byte-Order-Mark) ist bei UTF-8 nicht zwingend vorgeschrieben.
    https://de.wikipedia.org/wiki/Byte_Order_Mark
    Bei UTF-8 stellt sich das Problem der Byte-Reihenfolge zwar nicht, doch ein BOM am String- oder Dateianfang ist erlaubt, um die Verwendung von UTF-8 als Kodierung zu kennzeichnen.
  2. Ein Text, welcher nur aus Zeichen des ASCII 7-Bit Zeichensatzes besteht, ist sowohl in ASCII, ANSI und UTF-8 (ohne BOM) absolut identisch und kann nicht unterschieden werden.

Re: [Gelöst] File.CREATE in UTF-8 wird zu ANSI

24. Mai 2017 10:18

Hier sind ist Artikel von Vjeko und ein Beispielobjekt zur Analyse der BOM (sofern vorhanden), um die Codierung einer Unicodetextdatei zu ermittlen.
Detect file encoding in C/AL using .NET Interop

Re: File.CREATE in UTF-8 wird zu ANSI

29. September 2017 15:21

Kowa hat geschrieben:Entweder hatte ich ein Cacheproblem, oder Notepad++ zeigt falsch an :roll: .

Das ist tatsächlich ein Bug im Notepad++, Ursache eben entdeckt :-) .

Wenn man eine Datei mit Sonderzeichen erzeugt, erst ohne File.Textencoding (= OEM850) und anschließend mit Textencoding::UTF8 überschreibt, dann bietet Notepad++ ja das Neuladen wegen der Veränderung an. Dann wird der Dateiinhalt aber nicht korrekt dargestellt, erst beim manuellen Umstellen der Kodierung auf UTF-8 oder alternativ die Datei schließen und erneut öffnen.