Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Stream mit UTF8-Daten dekodieren? (https://www.delphipraxis.net/155373-stream-mit-utf8-daten-dekodieren.html)

ralfiii 20. Okt 2010 16:48

Delphi-Version: 2010

Stream mit UTF8-Daten dekodieren?
 
Hallo!

Ich hole mir ein paar Settings von einer Komponente als Stream ab und möchte dann den Stream weiterverarbeiten. Im Stream stehen die Daten aber UFT8-kodiert und mit dem 3-byte BOM drin.
Wie wandle ich das gscheit um?

Im Moment mach ich das über den Umweg einer TStringList, müsste aber netter gehen, oder?

Delphi-Quellcode:
  strm:=TMemoryStream.Create;
  MyComp.SaveToStream(strm);

  // das hier sollte doch simpler gehen, oder?
  with TStringList.Create do
  begin
       strm.Position:=0;
       LoadFromStream(strm, TEncoding.UTF8);
       s:=Text;
       Free;
  end;
Danke,
Ralf

Sir Rufo 20. Okt 2010 17:34

AW: Stream mit UTF8-Daten dekodieren?
 
Delphi-Quellcode:
function StringSaveToFile( const Str, FileName : string;
  const EraseFile : boolean ) : boolean;
  var
    fs : TFileStream;
    Size : integer;
    Buffer, Preamble : TBytes;
    Encoding : TEncoding;
    CreateFile : boolean;
  begin
    Result := False;
    try
      CreateFile := EraseFile or not FileExists( FileName );
      if CreateFile then
        fs := TFileStream.Create( FileName, fmCreate )
      else
        fs := TFileStream.Create( FileName, fmOpenReadWrite );
      try
        if CreateFile then
          begin
            Encoding := TEncoding.default;
            Preamble := Encoding.GetPreamble;
            if Length( Preamble ) > 0 then
              fs.WriteBuffer( Preamble[ 0 ], Length( Preamble ) );
          end
        else
          begin
            Encoding := nil;
            Size := fs.Size - fs.Position;
            if Size > 64 then
              Size := 64;
            SetLength( Buffer, Size );
            TEncoding.GetBufferEncoding( Buffer, Encoding );
            fs.Seek( 0, soFromEnd );
          end;
        Buffer := Encoding.GetBytes( Str );
        fs.WriteBuffer( Buffer[ 0 ], Length( Buffer ) );
      finally
        fs.Free;
      end;

    except
      on E : Exception do
        ;
    end;
  end;

function StringLoadFromFile( const FileName : string ) : string;
  var
    fs : TFileStream;
    Size : integer;
    Buffer : TBytes;
    Encoding : TEncoding;
  begin
    Result := '';
    try

      Encoding := nil;
      if FileExists( FileName ) then
        begin
          fs := TFileStream.Create( FileName, fmOpenRead );
          try

            Size := fs.Size - fs.Position;
            SetLength( Buffer, Size );
            fs.read( Buffer[ 0 ], Size );

            Size := TEncoding.GetBufferEncoding( Buffer, Encoding );
            Result := Encoding.GetString
              ( Buffer, Size, Length( Buffer ) - Size );

          finally
            fs.Free;
          end;
        end;

    except
      on E : Exception do
        ;
    end;
  end;

shmia 20. Okt 2010 18:25

AW: Stream mit UTF8-Daten dekodieren?
 
Anstelle eines MemoryStreams würde ich einen TStringStream verwenden.
Der Zugriff auf die Daten wird damit einfach bequemer.
Delphi-Quellcode:
strm:=TStringStream.Create;
MyComp.SaveToStream(strm);
strm.Seek(soFromBeginning   , 2); // BOM überspringen
utf8codierterstring := strm.ReadString(strm.Size);
// hier brauchst du nur noch eine Funktion, die UTF8 in
// einen AnsiString oder WideString wandelt, jenachdem
// was gewünscht wird.

Bummi 20. Okt 2010 19:54

AW: Stream mit UTF8-Daten dekodieren?
 
Zitat:

strm.Seek(soFromBeginning , 2); // BOM überspringen
erklärst Du mir das kurz?

ich hätte 3 erwartet wg. BOM = EF BB BF

himitsu 20. Okt 2010 20:06

AW: Stream mit UTF8-Daten dekodieren?
 
Zitat:

Zitat von Bummi (Beitrag 1056804)
ich hätte 3 erwartet wg. BOM = EF BB BF

Sind es auch ... halt nee, es ist nur ein Unicodezeichen, welches eigentlich keines ist und als MarkerChar genutzt wird. :angel:
http://www.unicode.org/charts/PDF/UFFF0.pdf (Unicode $FFFE = UTF-8-kodiert $EF$BB$BF)

Zum Umkodieren gibt es in der System-Unit einige alte Funktionen, mit einem "UTF8" im Namen
und ansonsten nutzt man jetzt (seit D2009) die Methoden von TEncoding.

Man könnte also auch erst umwandeln und danach dann das erste Zeichen rauslöschen, wenn es #$FFFE entspricht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz