从sybase数据库里面读出的是utf8编码格式,用delphi自带的uft8tounicode函数会出现这样的问题:字符结束处或者中英文字符的边界处出现丢字符情况,C#中也出现了类似的问题,但是给以用过utf8类自带的读取字节流的方法转化出来,delphi一直找不到,各位大侠有什么好办法吗?

解决方案 »

  1.   

    抄現:
    --------------
    function Utf8Decode(const S: UTF8String): WideString;    function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal;
          Source: PAnsiChar; SourceBytes: Cardinal): Integer;
        var
          i, count: Cardinal;
          c: Byte;
          wc: Cardinal;
        begin
          if Source = nil then
          begin
            Result := 0;
            Exit;
          end;
          Result := -1;
          count := 0;
          i := 0;
          if Dest <> nil then
          begin
            while (i < SourceBytes) and (count < MaxDestChars) do
            begin
              wc := Cardinal(Source[i]);
              Inc(i);
              if (wc and $80) <> 0 then
              begin
                if i >= SourceBytes then Exit;          // incomplete multibyte char
                wc := wc and $3F;
                if (wc and $20) <> 0 then
                begin
                  c := Byte(Source[i]);
                  Inc(i);
                  if (c and $C0) <> $80 then Exit;      // malformed trail byte or out of range char
                  if i >= SourceBytes then Exit;        // incomplete multibyte char
                  wc := (wc shl 6) or (c and $3F);
                end;
                c := Byte(Source[i]);
                Inc(i);
                if (c and $C0) <> $80 then Exit;       // malformed trail byte            Dest[count] := WideChar((wc shl 6) or (c and $3F));
              end
              else
                Dest[count] := WideChar(wc);
              Inc(count);
            end;
            if count >= MaxDestChars then count := MaxDestChars-1;
            Dest[count] := #0;
          end
          else
          begin
            while (i < SourceBytes) do
            begin
              c := Byte(Source[i]);
              Inc(i);
              if (c and $80) <> 0 then
              begin
                if i >= SourceBytes then Exit;          // incomplete multibyte char
                c := c and $3F;
                if (c and $20) <> 0 then
                begin
                  c := Byte(Source[i]);
                  Inc(i);
                  if (c and $C0) <> $80 then Exit;      // malformed trail byte or out of range char
                  if i >= SourceBytes then Exit;        // incomplete multibyte char
                end;
                c := Byte(Source[i]);
                Inc(i);
                if (c and $C0) <> $80 then Exit;       // malformed trail byte
              end;
              Inc(count);
            end;
          end;
          Result := count + 1;
        end;var
      L: Integer;
      Temp: WideString;
    begin
      Result := '';
      if S = '' then Exit;
      SetLength(Temp, Length(S));  L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PAnsiChar(S), Length(S));
      if L > 0 then
        SetLength(Temp, L-1)
      else
        Temp := '';
      Result := Temp;
    end;
      

  2.   

    Delphi本身就有一個Utf8ToUnicode(Unit:system)
      

  3.   

    这些函数都用过,但是用adoquery.fields[0].asvariant读出的数据丢失了一些字节流。用这个函数的输入参数都是string类型。我可以用API函数得到,但是首先必须得到这个adoquery.Fields[0]的二进制字节流,这个用recordset.fields[0].getchunk(recordset.fields[0].actualsize)操作的时候会跳出"在此环境中不允许操作"的错误,我觉得可能是后台库为sybase的缘故。