![]() |
Ansi Encoding ohne Leerzeichen
Hallo
Ich schicke aus einer Delphi APP ein Logfile an Einen Windows Rechner. Diese Logfile soll in Notepad.exe dargestellt werden.
Delphi-Quellcode:
Wie muss ich das Encoding beim Speichern einstellen damit nicht vor jedem Zeichen ein Leerzeichen steht?
function TLog.Internal_GetEmailFile: String;
var alogtext:String; begin result := ''; Internal_ReadFile(alogtext); if tFile.Exists(fEmailFile) then Tfile.Delete(fEmailFile); TFile.WriteAllText(femailfile,UTF8Encode(aLogText), TEncoding.UTF8 ); result := femailfile; end; |
AW: Ansi Encoding ohne Leerzeichen
TEncoding.ANSI
(Das war einfach :-)) |
AW: Ansi Encoding ohne Leerzeichen
PS: Das ist kein Leerzeichen, es ist eine 0.
Die 0 vom HighByte des Unicode, wenn da das Char maximal als #255 ist. :zwinker: Aber wenn die 0 auch bei deinem TEncoding.UTF8 vorhanden war, dann stimmt bei dir noch was Anderes nicht. |
AW: Ansi Encoding ohne Leerzeichen
Es war bei Tencoding.Ansi
und bei Tencoding.UTF8 vorhanden :( WriteAllText Schreibt im UTF 8 fall sogar (laut source) eine BOM davor. Es ist total seltsam |
AW: Ansi Encoding ohne Leerzeichen
Das
Delphi-Quellcode:
ist doch völlig überflüssig (wenn nicht sogar schädlich!), denn
Utf8Encode
Delphi-Quellcode:
erwartet dort einen
WriteAllText
Delphi-Quellcode:
und übernimmt selbst das Encoding.
string
|
AW: Ansi Encoding ohne Leerzeichen
Ich habe es jetzt umgestellt auf folgendes Verfahren...
Delphi-Quellcode:
....Notepad.exe gibt mir das mit chinesischen Zeichen wieder :(
function TLog.Internal_GetEmailFile: String;
var alogtext:String; AnsiArr:Tbytes; UniCodeArr:tBytes; begin result := ''; Internal_ReadFile(alogtext); if tFile.Exists(fEmailFile) then Tfile.Delete(fEmailFile); unicodeArr := Tencoding.Unicode.GetBytes(aLogtext); AnsiArr := TEncoding.Convert(Tencoding.Unicode,Tencoding.ANSI, unicodeArr ); Tfile.WriteAllBytes(femailfile,AnsiArr); // TFile.WriteAllText(femailfile,aLogText, TEncoding.ANSI ); result := femailfile; end; Welches ist die native codierung von Strings und Dateien in Delphi Tokyo für Android apps? Das ist ein Copy&Paste aus dem Ctrl+F7 aud aLogtext
Code:
Also schon beim Lesen der Datei sind überflüssige #000 drin. Nur am ende ist keines drin. Ich weiß nicht wie die dort rein kommen, bzw wenn sie teil des zeilenumbruchs sind, warum am ende dann keine #000 steht.
'4.08.17 17:59:52 EnteredBackground'#012#000'4.08.17 17:59:53 WillBecomeInactive'#012#000'4.08.17 17:59:55 WillBecomeForeground'#012#000'4.08.17 17:59:55 BecameActive'#012#000'4.08.17 17:59:58 WillBecomeInactive'#012#000'4.08.17 18:00:00 EnteredBackground'#012#000'4.08.17 18:00:00 BecameActive'#012#000'4.08.17 18:00:00 WillBecomeInactive'#012#000'4.08.17 18:00:04 WillBecomeForeground'#012#000'4.08.17 18:00:04 BecameActive'#012#000'4.08.17 18:00:09 EnteredBackground'#012#000'4.08.17 18:00:09 WillBecomeInactive'#012#000'4.08.17 18:00:14 WillBecomeForeground'#012#000'4.08.17 18:00:14 BecameActive'#012#000'4.08.17 18:00:48 EnteredBackground'#012#000'4.08.17 18:00:54 WillBecomeInactive'#012#000'4.08.17 18:01:46 Log active'#012#000'4.08.17 18:01:46 App Start'#012#000'4.08.17 18:01:49 FinishedLaunching'#012#000'4.08.17 18:03:42 Log active'#012#000'4.08.17 18:03:42 App Start'#012#000'4.08.17 18:03:53 FinishedLaunching'#012#000'4.08.17 18:06:05 WillBecomeForeground'#012#000'4.08.17 18:06:05 BecameActive'#012#000'4.08.17 18:06:16 EnteredBackground'#012#000'4.08.17 18:06:17 WillBecomeInactive'#012#000'4.08.17 18:06:21 WillBecomeForeground'#012#000'4.08.17 18:06:21 BecameActive'#012#000'4.08.17 18:06:55 EnteredBackground'#012#000'4.08.17 18:07:02 WillBecomeInactive'#012#000'4.08.17 18:07:33 WillBecomeForeground'#012#000'4.08.17 18:07:33 BecameActive'#012#000'4.08.17 18:11:01 EnteredBackground'#012#000'4.08.17 18:11:01 WillBecomeInactive'#012#000'7.08.17 12:18:09 Log active'#012#000'7.08.17 12:18:09 App Start'#012#000'7.08.17 12:18:22 FinishedLaunching'#012#000'7.08.17 12:18:29 WillBecomeForeground'#012#000'7.08.17 12:18:30 BecameActive'#012
|
AW: Ansi Encoding ohne Leerzeichen
Ok Diese Version funktioniert für Notepad.exe, leider sind dann die Zeilenumbrüche weg.
Sublime Text zeigt dann aber nur eine HExDump an.
Delphi-Quellcode:
Zeilenumbrüche mache ich so mit linefeed...
function TLog.Internal_GetEmailFile: String;
var alogtext:String; AnsiArr:Tbytes; UTF8Arr:tBytes; begin result := ''; Internal_ReadFile(alogtext); if tFile.Exists(fEmailFile) then Tfile.Delete(fEmailFile); UTF8Arr := Tencoding.UTF8.GetBytes(aLogtext); AnsiArr := TEncoding.Convert(Tencoding.UTF8,Tencoding.ANSI, UTF8Arr ); Tfile.WriteAllBytes(femailfile,AnsiArr); // TFile.WriteAllText(femailfile,aLogText, TEncoding.ANSI ); result := femailfile; end;
Delphi-Quellcode:
aText := Datetimetostr(now) + ' ' + aText + linefeed;
FStream.Write(aText[1], length(aText) * Sizeof(aText[1]) ); |
AW: Ansi Encoding ohne Leerzeichen
OK,Das hier ist die Lösung.
Delphi-Quellcode:
Ich weiß nicht wie die ganzen "null" werte da rein kommen, aber es fühlt sich so ein bisschen an als würde der Filestream einen Nulltermnierten string schreiben, und auch die #0 in die Datei speichern.
function TLog.Internal_GetEmailFile: String;
var alogtext:String; begin result := ''; Internal_ReadFile(alogtext); alogtext := aLogtext.Replace(''+linefeed, ''+carriageReturn+''+linefeed, [rfReplaceAll] ); alogtext := alogtext.Replace(''#0,'',[rfReplaceAll]); if tFile.Exists(fEmailFile) then Tfile.Delete(fEmailFile); TFile.WriteAllText(femailfile,aLogText, TEncoding.UTF8 ); result := femailfile; end; |
AW: Ansi Encoding ohne Leerzeichen
In 'nem FileStream ist alles drin, bei 'nem #0-terminierten String auch die #0, da sie ein Teil von ihm ist.
|
AW: Ansi Encoding ohne Leerzeichen
Zitat:
|
AW: Ansi Encoding ohne Leerzeichen
Jain.
String ist ein Delphi-String mit Unicode (seit 2009) Delphi-Strings haben eine Längenangabe (wie in dynamisches "Array of Char"), außerdem besitzen sie aus Kompatibilitätsgründen und für "einfache" PChar-Casts auch eine implizit abschließende Doppel-Null (#0#0). |
AW: Ansi Encoding ohne Leerzeichen
Kenne mich da nicht mit aus, aber ist nicht inzwischen alles, was nicht im Bereich von String[1] bis String[255] liegt, ein nullterminierter String?
Aus die Schnelle fand ich das: ![]() |
AW: Ansi Encoding ohne Leerzeichen
Nein.
String (Delphi 1) und String[Länge] nennen sich jetzt "ShortString" und das ist ein Record/StaticArray mit einem Längen-Byte auf Char[0]. (darum fangen in Delphis Strings auch bei 1 an) Der LongString, aka String, AnsiString und UnicodeString, ist ein aufgemotztes dynamisches Array (array of char), mit CodePage neben dem Längen-Integer und hinten ein implizites #0#0. |
AW: Ansi Encoding ohne Leerzeichen
Zitat:
Hm, dessen war ich mir nicht bewusst. So ein bisschen ärgert es mich auch. Aber gut, genau hinsehen hätte mir sowas ja auch verraten. bekomme ich die doppelnullterminierung auch vom Tstringhelper.toCharArray und Tencoding.unicode.Getbytes ? Sprich was ist der richtige Buffer für filestream write? |
AW: Ansi Encoding ohne Leerzeichen
Habe gerade mal in meinem ollen Delphi 7 probiert:
Delphi-Quellcode:
Das liefert mir
var
s1 : String[1]; s255 : String[255]; s : String; sShort : ShortString; begin ShowMessage(Format('s = %d, s1 = %d, s255 = %d, sShort = %d', [SizeOf(s),SizeOf(s1),SizeOf(s255),SizeOf(sShort)])); end;
Code:
Daraus schließe ich jetzt einfach mal (bitte korrigiert mich):
s = 4, s1 = 2, s255 = 256, sShort = 256
String[255] entspricht ShortString, String[1] bis String[255] verhalten sich wie schon beim alten Turbopascal. (Array of Char, bei dem an Position 0 die Längenangabe des tatsächliche genutzten Teils des Arrays steht.) String ist, wie himitsu beschrieb, eine nullterminierte Zeichenfolge. |
AW: Ansi Encoding ohne Leerzeichen
ich schreibe das jetzt alles so
Delphi-Quellcode:
Datei wird wie folgt erzeugt, damit es passt
aText := Datetimetostr(now) + ' ' + aText + linefeed;
aByteArr := TEncoding.Utf8.GetBytes(aText); //FStream.Write(aText[1], length(aText) * Sizeof(aText[1]) ); FStream.WriteData(aByteArr, Length(aByteArr));
Delphi-Quellcode:
Ich öffne mehrere (wenige und kleine)Logfiles und hänge sie hintereinander in einen String.
if not TFile.Exists(fLogFile) then
Begin FileOpenMode := fmCreate; fStream := TFileStream.create( self.fLogFile, FileOpenMode ); Preambel := Tencoding.UTF8.GetPreamble; fStream.WriteData(Preambel,length(Preambel)); fStream.free; End;
Delphi-Quellcode:
Dann erzeuge ich aus dem String eine einzige Datei für ein Email Attchment.
aText := aText + TFile.ReadAllText(flogfile,Tencoding.UTF8);
Delphi-Quellcode:
Diese Datei kann ich dann tatsächlich per notepad.exe öffnen.
function TLog.Internal_GetEmailFile: String;
var alogtext:String; begin result := ''; Internal_ReadFile(alogtext); alogtext := aLogtext.Replace(''+linefeed, ''+carriageReturn+''+linefeed, [rfReplaceAll] );//für Notepad.exe alogtext := alogtext.Replace(''#0,'',[rfReplaceAll]);//einfach zur sicherheit. if tFile.Exists(fEmailFile) then Tfile.Delete(fEmailFile); TFile.WriteAllText(femailfile,aLogText, TEncoding.UTF8 );//erzeugt eine UTF8 Preambel (BOM) result := femailfile; end; Problem ist also gelöst.. und viel über kodierung und strings dabei gelernt. |
AW: Ansi Encoding ohne Leerzeichen
Zitat:
String[1] bis String[255] sind ShortString (DatenFormat-Definition). Und LongString (AnsiString und UnicodeString) sowie WideString arbeiten mit Längen-Bytes/Integern, aber haben auch PChar-Charakteristiken drin, die aber vom String selber nicht verwendet werden. WideString ist fast so wie LongString, nur etwas Einfacher und es wird von der OleAuth32.dll verwaltet. (WinAPI und deren SpeicherManager)
Delphi-Quellcode:
var
S1, S2, S3: string; S1 := 'abc'#0'def'; S2 := Copy(S1); // S2 := S1; ... damit auch wirklich der Inhalt kopiert wird, da LongStrings referenzverwaltet sind und sonst nur den Pointer, aber nicht den Inhalt kopieren S3 := PChar(S1); ShowMessage(Format('%d %d %d', [Length(S1), Length(S2), Length(S3)])); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz