流和字节的转换

为防止找不到相关内容,所以,在这里留一个印记。

 /--------流转换Begin------- //
function StreamToBytes(aStream:TStream):TBytes;
begin
 // aStream := TMemoryStream.Create;  //此处,不需要初始化流
  try
    SetLength(Result, aStream.Size);
    aStream.Position := 0;
    aStream.Read(Result[0], aStream.Size);
  finally
    aStream.Free;
  end;
end;


 //使用Stream前,需要Stream.Position := 0; 否则,读取不到内容
function BytesToStream(aBytes:TBytes):TStream;
var
  aStream: TStream;
begin
  aStream := TMemoryStream.Create;
  try
    aStream.Write(aBytes[0],length(aBytes));
    aStream.Position := 0;
    result :=aStream;
  finally
    //aStream.Free;  //此处,不可释放
  end;
end;


function StreamToHexStr(aStream:TStringStream):string;  //使用Tstream总不成功,不知道有好的办法没有?!虽然可以使用StreamToBytes,再BytesToHexStr

/现在知道了,Tstream是个虚函数,必须有载体才能使用。新单元增加了TBytesStream,方便了许多
var
  Len: Integer;
begin
  aStream.Position :=0;
  Len :=aStream.size;
  Result :='';
  SetLength(Result, len*2);
  BinToHex(PAnsiChar(aStream.DataString), PAnsiChar(Result), len); 
  //BinToHex(PAnsiChar(aStream), PAnsiChar(Result), len);     //用stream不成功
 // BinToHex(@aStream, PAnsiChar(Result), len);                //用stream不成功
end;


举例更容易看清楚使用方法:

procedure TForm1.Button2Click(Sender: TObject);   //StreamToBytes
var
  Stream: TStream;
  Arr_Byte: TBytes;
  isize:integer;
begin
  Stream := TMemoryStream.Create; //必须初始化

  Memo1.lines.SaveToStream(Stream);
  //isize :=Stream.Size;
 // showmessage(inttostr(isize));
  Stream.Position :=0;
  Arr_Byte :=StreamToBytes(Stream);
  edit1.Text :=BytesToHexStr(Arr_Byte,length(Arr_Byte));
end;

procedure TForm1.Button3Click(Sender: TObject);  //BytesToStream
var
  Stream: TStream;
  Arr_Byte: TBytes;
  i:integer;
begin
  SetLength(Arr_Byte, 7);
  for i := 0 to High(Arr_Byte) do Arr_Byte[i] := $41 + i;
  memo1.Lines.LoadFromStream(BytesToStream(Arr_Byte));
  edit1.Text :=memo1.Text;
end;

procedure TForm1.Button7Click(Sender: TObject);  //StreamToHexStr
var Stream: TstringStream;
begin
   Stream := TStringStream.Create('');
   
   Memo1.lines.SaveToStream(Stream);
   edit1.text :=StreamToHexStr(Stream);
end;



把更新的单元发到这里,好找寻D7EncodedText.pas(20150324)

unit D7EncodedText; { V1.5        ---2015.0324----   ---------序---------     实际上,数组,字符串,整数等都是存在字节内的,本质上,连续的字节就形成流。     流的操作,需要注意,经常要初始化,读写都需要stream.Position := 0;     流的关键函数就是system.move,它主要对内存进行操作的   ---------序完---------     1.D7(delphi2007)之前的memo等都只支持AnsiString;本单元主要为<=D7的使用;仅此纪念D7的了;  2. 因Delphi 2010之后的默认字符集都是Unicode了,简化了很多(主要使用了TEncoding类);   Memo可以直接支持读入ASCII,UTF-8,Unicode;写则可以指定写入的编码格式。  3.在中文操作系统下,D7默认使用的GB2312字符集,故AnsiString的字符集可看做GB2312;  缺省的编译选项下,编译器认为String就是AnsiString字符串(可以使用$H编译开关来进行修改),保存就是ASCII。  4.D7前的widestring实际就是Unicode字符,默认string等同于AnsiString。参见CoderOfUnicode。  5.觉得最重要的是理解到字符存为2进制按Byte放置的,所以,字符的1个Byte内容可转为2位HexStr;    同样,2位HexStr可转换为1字节内容(对这些连续的Byte可根据Ansi,UTF8,Unicode解码 就得到对应的字符的)。    这种方式才是最值得提倡的和便于理解的。 Byte为1字节可直接将小于255的值直接赋给它,intger,char,Hex值等;    如:ABtye :=255; $FF; Byte('A');  6.个人觉得转码实际就是byte的操作,用Byte来做转换方便得多的(Byte 0..255,小于256的整数赋值给byte就是操作Byte的了)。    比如我写的coderToUTF8Str。  7.注意:Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。所以,Big endian方式    是所见即所得,即编码'一':U4E 00;BE方式存储后用UltraEdit打开也是4E 00(先存高字节);但Little endian方式存储后则为    00 4E(先存小端低字节00);  8.增加StreamToBytes和BytesToStream,以便转换流的操作(2015-03-20);

 2015-03-20

Notepad(记事本)只支持四种格式:ANSI/Unicode/Unicode big endian/UFT-8,在Delphi中如何判断与读取这些不同格式的文本呢?

首先,不同编码的文本,是根据文本的前两个字节来定义其编码格式的。定义如下:

ANSI: 无格式定义; Unicode: 前两个字节为FFFE; Unicode big endian: 前两字节为FEFF; UTF-8: 前两字节为EFBB; 实际前3字节为EF BB BF }

interface uses    SysUtils,Classes,Windows,    Variants;

type     FReadText=array of WideString;   TBytes = array of Byte;

  TTextFormat=(Ansi, Unicode, UnicodeBigEndian, Utf8);

{ TBytesStream }

  TBytesStream = class(TMemoryStream)   private     FBytes: TBytes;     FCapacity: Longint;     FMemory: Pointer;     FSize, FPosition: Longint;   protected     function Realloc(var NewCapacity: Longint): Pointer; override;   public     constructor Create(const ABytes: TBytes); overload;     property Bytes: TBytes read FBytes;   end;

resourcestring sMyNewErrorMessage = 'MemoryStream Error!';

const   TextFormatFlag: array[Ansi..Utf8] of word=($0000,$FFFE,$FEFF,$EFBB);   MemoryDelta = $2000; { Must be a power of 2 }

  function  UnicodeSave(const FileName:string;WS:widestring):boolean;   function  UnicodeRead(const FileName:string):WideString;

  function  UnicodeBigSave(const FileName:string;WS:widestring):boolean;   function  UnicodeBigRead(const FileName:string):WideString;

  function  UTF8Save(const FileName:string;WS:widestring):boolean;   function  UTF8Read(const FileName:string):WideString;

  function  AnsiSave(const FileName:string;WS:widestring):boolean;   function  AnsiRead(const FileName:string):WideString;

  function GetTextType(const FileName: string): String;   //返回文本格式信息

  function TextRead(const FileName:string):FReadText; //读取各种格式   function TextSave(const FileName:string;WS:widestring):boolean;  //保存原格式

  function UnicodeEncode(Str:string;CodePage:integer):WideString;  //unicode编码   function UnicodeDecode(Str:WideString;CodePage:integer):string;  //unicode解码

  function WStrToStr(const ws: WideString; codePage: Word): AnsiString; //宽字符串转单字符串,等同于UnicodeEncode   function StrToWStr(const s: AnsiString; codePage: Word): WideString;  //单字符串转宽字符串,等同于UnicodeDecode //  function WideStringToUCS4String(const ws : WideString) : UCS4String;

  function HexToInt(s: string): Integer;    //IntToHex函数,D7自带;实际应该写为HexStrToInt   function IntToBinStr(i: integer): string;  //integer范围signed 32-bit   function ByteToHexStr(AByte : Byte ) : string;    //单字节处理   function HexStrToByte(HexS: String ) : Byte;     //2位16进制字符串转为1个字节   function HexStrToDec(HexStr: AnsiString):AnsiString; //按每2位Hex字符转换为3位十进制数字字符串

  //以下是连续字符和字节的处理   function BytesOf(const Val: AnsiString): TBytes;                        //Ansistring字符串的字节数组形式   function HexStrToBytes(const HexStr: AnsiString): TBytes;               //连续的16进制数的字节数组形式   function BytesToHexStr(ABytes: TBytes; len: Integer): AnsiString;       //字节数组的 Ansistring字符串形式

  //机内码 转 Ansi(GB2312)字符,中文系统下:16进制/无空格分隔 ;   分隔字符串当然不能是0..9,A..F,a..f   function CoderToAnsiStr(HexS: String;const Delimited:string=''):String;   function CoderToUTF8Str(HexS: String;const Delimited:string=''):String;  //机内码 转 Utf-8   function CoderToUnicodeStr(HexS: String;const Delimited:string=''):String;   //机内码 转 unicode字符:默认16进制/无空格分隔   function CoderToUnicodeBigEndianStr(HexS: String;const Delimited:string=''):String;   //机内码 转 unicodeBigEndian   function CoderToUtf32Str(HexS: String;const Delimited:string=''):String;              //机内码 转 Utf-32   function CoderToUtf32BigEndianStr(HexS: String;const Delimited:string=''):String;    //机内码 转 Utf-32 BigEndian

  function UTF8StrToCoder(S:String; const Delimited:string=''):string;        //Utf-8 转 机内码   function AnsiStrToCoder(S: String;const Delimited:string=''):String;        //Ansi(包括GB2312,准确是当前的字符集)字符转机内码   function UniCodeStrToCoder(S:String;const Delimited:string=''):String;             //unicode字符转机内码   function UniCodeBigEndianStrToCoder(S:String; const Delimited:string=''):string;   //unicodeBigEndian字符转机内码   function UTF32StrToCoder(S:String; const Delimited:string=''):string;          //  Utf-32 转 机内码   function UTF32BigEndianStrToCoder(S:String; const Delimited:string=''):string; //Utf-32 BigEndian 转 机内码

  function  BinFileToHexStr(BinFileName:string):string;                         //按2进制文件读取文件为HexStr字符串(包括Bin文件)   function  HexStrToBinFile(HexStr:string;BinFileName:string):Boolean;

  function StreamToBytes(aStream:TStream):TBytes;         //流to字节串(字节数组),本质上是一个东西的   function BytesToStream(aBytes:TBytes):TStream;         //使用Stream前,需要Stream.Position := 0; 否则,读取不到内容

  {**注意TStream 是抽象类, 只能通过其子类实例化; 若使用TStream是得不到内容的,它为基类,必须用其他流来代替}   function StreamToHexStr(aStream:TStringStream):string; overload; //重载,TStringStream类的实现   function StreamToHexStr(aStream:TMemoryStream):string; overload; //重载,TMemoryStream类的实现   function StreamToHexStr(aStream:TBytesStream):string; overload; //重载,TBytesStream类的实现

implementation

{ TBytesStream }    ///---------参照delphi2010写的字节流类型,比较好用------------/// constructor TBytesStream.Create(const ABytes: TBytes); begin   inherited Create;   FBytes := ABytes;   SetPointer(Pointer(FBytes), Length(FBytes));   FCapacity := FSize; end;

function TBytesStream.Realloc(var NewCapacity: Integer): Pointer; begin   if (NewCapacity > 0) and (NewCapacity <> FSize) then     NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);   Result := Pointer(FBytes);   if NewCapacity <> FCapacity then   begin     SetLength(FBytes, NewCapacity);     Result := Pointer(FBytes);     if NewCapacity = 0 then       Exit;     if Result = nil then raise EStreamError.CreateRes(@sMyNewErrorMessage);   end; end;

//Unicode存 function  UnicodeSave(const FileName:string;WS:widestring):boolean; var  S: string; begin   Result :=False;   if WS = '' then Exit;   with TMemoryStream.Create do    try      S := #$FF#$FE;      Write(S[1], Length(S));      Write(WS[1], Length(WS) * SizeOf(WideChar));      Position := 0;      SaveToFile(FileName);      Result :=True;    finally      Free;    end; end;

//Unicode读取 function UnicodeRead(const FileName:string):WideString;  function WideStringToString(const WS: WideString; CodePage: Word): string;  var   InputLength,OutputLength:Integer; begin   InputLength := Length(WS);   OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil);   SetLength(Result, OutputLength);   WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil); end;

var   S: string;   WS:WideString ; begin   Result :='';   if not FileExists(FileName) then Exit;   with TMemoryStream.Create do   try     LoadFromFile(FileName);     if Size < 4 then Exit;     SetLength(S, 2);     Read(S[1], Length(S));    // if Copy(S, 1, 2) <> #$FF#$FE then Exit;  //不加此句可以尝试读取非Unicode的格式文件    { if Copy(S, 1, 2) <> #$FF#$FE     then       SetLength(WS, Size  div SizeOf(WideChar))     else  }      SetLength(WS, (Size - 2) div SizeOf(WideChar));      Read(WS[1], Length(WS) * SizeOf(WideChar));      //Result :=WideStringToString(WS,1252);      Result :=WS;   finally     Free;   end; end;

//Unicode big endian存 function  UnicodeBigSave(const FileName:string;WS:widestring):boolean; var  S: string;      i:integer; begin   Result :=False;   if WS = '' then Exit;   with TMemoryStream.Create do    try      S := #$FE#$FF;      Write(S[1], Length(S));

     for i := 1 to Length(ws) do        ws[i] := WideChar(Swap(Word(ws[i])));   //交换高低字节

     Write(WS[1], Length(WS) * SizeOf(WideChar));      Position := 0;      SaveToFile(FileName);      Result :=True;    finally      Free;    end; end;

//Unicode  big endian读取 function UnicodeBigRead(const FileName:string):WideString; var   S: string;   WS:WideString ;   i:integer; begin   Result :='';   if not FileExists(FileName) then Exit;   with TMemoryStream.Create do   try     LoadFromFile(FileName);     if Size < 4 then Exit;     SetLength(S, 2);     Read(S[1], Length(S));    // if Copy(S, 1, 2) <> #$FE#$FF then Exit;  //不加此句可以尝试读取非Unicode big endian的格式文件     SetLength(WS, (Size - 2) div SizeOf(WideChar));     Read(WS[1], Length(WS) * SizeOf(WideChar));

    for i := 1 to Length(ws) do        ws[i] := WideChar(Swap(Word(ws[i])));   //交换高低字节

     Result :=WS;   finally     Free;   end; end;

//UTF-8存 function  UTF8Save(const FileName:string;WS:widestring):boolean; var  S: string; begin   Result :=False;   if WS = '' then Exit;   with TMemoryStream.Create do   try     S := #$EF#$BB#$BF;     Write(S[1], Length(S));     S := AnsiToUtf8(WS);     Write(S[1], Length(S));     Position := 0;     SaveToFile(FileName);     Result :=True;   finally     Free;   end; end;

//UTF-8读取 function UTF8Read(const FileName:string):WideString; var   S: string; begin   Result :='';   if not FileExists(FileName) then Exit;

 with TMemoryStream.Create do  try    LoadFromFile(FileName);    SetLength(S, Size);    Read(S[1], Length(S));   // if Copy(S, 1, 3) <> #$EF#$BB#$BF then Exit;     //不加此句可以尝试读取非UTF-8的格式文件    Result := Utf8ToAnsi(Copy(S, 4, MaxInt));  finally   Free;  end; end;

//Ansi读取可以直接用 { Memo1.Lines.LoadFromFile(Edit1.Text); //读取 Memo1.Lines.savetoFile(Edit1.Text);   //保存  }   //Ansi读取 function AnsiRead(const FileName:string):WideString; var   S: string; begin   Result :='';   if not FileExists(FileName) then Exit;

 with TMemoryStream.Create do  try    LoadFromFile(FileName);    SetLength(S, Size);    Read(S[1], Length(S));    Result := S;  finally    Free;  end; end;

//Ansi存 function  AnsiSave(const FileName:string;WS:widestring):boolean; var  S: string; begin   Result :=False;   if WS = '' then Exit;   S:=WS;   with TMemoryStream.Create do   try     Write(S[1], Length(S));     Position := 0;     SaveToFile(FileName);     Result :=True;   finally     Free;   end; end;

function WordLoHiExchange(w:Word):Word; register;    asm XCHG AL, AH end; { TextFormat返回文本编码类型,sText未经处理的文本 }

function GetTextType(const FileName: string): String; var    w: Word;  begin    with TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone) do     try        Read(w,2);       w:=WordLoHiExchange(w);//因为是以Word数据类型读取,故高低字节互换       if w = TextFormatFlag[Unicode] then         Result := 'Unicode'       else if w = TextFormatFlag[UnicodeBigEndian] then         Result:= 'UnicodeBigEndian'       else if w = TextFormatFlag[Utf8] then       //本来需要判断第3个字节的,但通常可省略         Result := 'Utf8'       else         Result := 'Ansi';             //实际是无文件头,而不是$0000判断的哦     finally        Free;     end;  end;

function TextRead(const FileName:string):FReadText;     //自动判断文件BOM,自动载入文件的编码类型 var   S: string;   w: Word;   WS:WideString ;   i:integer; begin   SetLength (Result,2);  //第1个存返回的字符串,第2个为文件类型

  Result[0] :='';   if not FileExists(FileName) then Exit;         with TMemoryStream.Create do     try       LoadFromFile(FileName);       if Size < 4 then Exit;

      Read(w,2);       w:=WordLoHiExchange(w);//因为是以Word数据类型读取,故高低字节互换       if w = TextFormatFlag[Unicode] then         Result[1] := 'Unicode'       else if w = TextFormatFlag[UnicodeBigEndian] then         Result[1] := 'UnicodeBigEndian'       else if w = TextFormatFlag[Utf8] then       //本来需要判断第3个字节的,但通常可省略         Result[1] := 'Utf8'       else         Result[1] := 'ANSI';             //实际是无文件头,而不是$0000判断的哦

                 //^^^^^需要将游标重置到文件头位置      if  (Result[1]='Unicode') or (Result[1]='UnicodeBigEndian')      then        begin          Seek(2,soFromBeginning);          SetLength(WS, (Size-2 ) div SizeOf(WideChar));

         Read(WS[1], Length(WS) * SizeOf(WideChar));

         if  (Result[1] = 'UnicodeBigEndian') then          //unicode big endian            for i := 1 to Length(ws) do             ws[i] := WideChar(Swap(Word(ws[i])));   //交换高低字节        end      else if  Result[1]='Utf8'      then        begin          Seek(0,soFromBeginning);          SetLength(S, Size);          Read(S[1], Length(S));          // Result[0] := Utf8ToAnsi(Copy(WS, 4, MaxInt));          WS :=Utf8ToAnsi(Copy(S, 4, MaxInt));        end      else                       //按Ansi处理        begin          Seek(0,soFromBeginning);          SetLength(S, Size);          Read(S[1], Length(S));          WS :=S;         //Result[0] :=WS;        end;

      Result[0] :=WS;     finally       Free;     end; end;

function TextSave(const FileName:string;WS:widestring):boolean; var   txtType: string;   //w: Word; begin   txtType :=GetTextType(FileName);   try     if txtType='Unicode'     then       UnicodeSave(FileName,WS)     else if  txtType='UnicodeBigEndian' then       UnicodeBigSave(FileName,WS)     else if  txtType='Utf8'             then       UTF8Save(FileName,WS)     else  //Ansi       AnsiSave(FileName,WS);     Result :=True;   except     Result :=False;   end; end;

function UnicodeEncode(Str:string;CodePage:integer):WideString; var   Len:integer; begin   Len:=Length(Str)+1;   SetLength(Result,Len);   Len:=MultiByteToWideChar(CodePage,0,PAnsiChar(Str),-1,PWideChar(Result),Len);   SetLength(Result,Len-1); //end is #0 end;

function UnicodeDecode(Str:WideString;CodePage:integer):string; var   Len:integer; begin   Len:=Length(Str)*2+1;  //one for #0   SetLength(Result,Len);   Len:=WideCharToMultiByte(CodePage,0,PWideChar(Str),-1,PAnsiChar(Result),Len,nil,nil);   SetLength(Result,Len-1); end;

function WStrToStr(const ws: WideString; codePage: Word): AnsiString; var   l: integer; begin   if ws ='' then     Result :=''   else   begin     l := WideCharToMultiByte(codePage,       WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,       @ws[1], - 1, nil, 0, nil, nil);     SetLength(Result, l - 1);     if l > 1 then       WideCharToMultiByte(codePage,         WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,         @ws[1], - 1, @Result[1], l - 1, nil, nil);   end; end; { WideStringToString }

function StrToWStr(const s: AnsiString; codePage: Word): WideString; var   l: integer; begin   if s ='' then     Result :=''   else   begin     l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PAnsiChar(@s[1]), - 1, nil, 0);     SetLength(Result, l - 1);     if l > 1 then       MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PAnsiChar(@s[1]),         - 1, PWideChar(@Result[1]), l - 1);   end; end; { StringToWideString }

 

---------进制转换------------/// ///参考的文章:http://www.2ccc.com/article.asp?articleid=3133 //十六进制(S)-->>十进制(I)  [重写:Jey] function HexToInt(s: string): Integer; begin          //$代表16进制 ,integer范围signed 32-bit   Result:=StrToInt('$'+s); end;

//十进制转换为二进制字符串  [重写:Jey] function IntToBinStr(i: integer): string; begin         //integer范围signed 32-bit  while i <>0 do  begin          //i mod 2取模,再使用format格式化    result:=Format('%d'+result,[i mod 2]);    i:=i div 2;  end end;

function ByteToHexStr(AByte : Byte ) : string; begin   Result:=Format('%.2x', [AByte]); end;

function HexStrToByte(HexS: String ) : Byte; var i:integer; begin   i:=StrToInt('$'+HexS);   if i<256   then     Result:=Byte(i)   else     Result:=Byte(0); end;

---------进制转换------------///

---------编码转换------------///

//Ansi的机内码转nsi字符,默认:中文系统下/16进制无空格分隔 function AnsiStrToCoder(S:string; const Delimited:string=''):string; var  i:integer; begin  Result :='';  for i:=1 to length(S) do  //用ord函数可以取得字符的ASCII码的值  try    if odd(i)    then    //result:=result+IntToHex(ord(s[i]),2) //可用      result:=result+Format('%.2x', [ord(S[i])])    else   // result:=result+IntToHex(ord(s[i]),2)+Delimited;   //可用      result:=result+Format('%.2x', [ord(S[i])])+Delimited;  except  end; end;

//Unicode的机内码转Ansi字符:默认16进制无空格分隔 function UniCodeStrToCoder(S:String; const Delimited:string=''):string; var  i:integer;  WS:WideString; begin   Result :='';   WS :=WideString(S);   //必须转换为widechar以获得Unicode编码  for i:=1 to length(WS) do  //用ord函数可以取得字符的ASCII码的值    //result:=result+IntToHex(ord(S[i]),4)+Delimited;             //unicode,可用   try     result:=result+IntToHex(ord(Swap(word(WS[i])) ),4)+Delimited;   //swap交换高低字节 ,这个出来的是unicode little endian   except   end; end;

function UniCodeBigEndianStrToCoder(S:String; const Delimited:string=''):string; var  i:integer;  WS:WideString; begin   Result :='';   WS :=WideString(S);   //必须转换为widechar以获得Unicode编码  for i:=1 to length(WS) do  //用ord函数可以取得字符的ASCII码的值    //result:=result+IntToHex(ord(S[i]),4)+Delimited;             //unicode,可用   try     result:=result+Format('%.4x', [ord(WS[i])])+Delimited;   except   end; end;

//UTF-8的机内码转Ansi字符:默认16进制无空格分隔 function UTF8StrToCoder(S:String; const Delimited:string=''):string; var  i:integer;  UTF8Str:UTF8String; begin   Result :='';   UTF8Str :=AnsiToUtf8(S);   //必须转换为TF8String以获得UTf-8编码  for i:=1 to length(UTF8Str) do  //用ord函数可以取得字符的ASCII码的值   try    result:=result+Format('%.2x', [ord(UTF8Str[i])])+Delimited;    //或者result:=result+ByteToHex(Byte(UTF8Str[i]))+Delimited;   except   end; end;

function UTF32StrToCoder(S:String; const Delimited:string=''):string; var U4:UCS4String;     i: Cardinal; begin   Result :='';   U4 :=WideStringToUCS4String(VarToWideStr(s));   for i:=0 to Length(U4)-2 do //最后1位为字符串结束标志0     if U4[i]>$FFFF then       Result:=Result+ IntToHex(Swap(word(U4[i]-$FFFF)),8)+Delimited     else       Result:=Result+ IntToHex(Swap(word(U4[i])) shl 16,8)+Delimited; end;

function UTF32BigEndianStrToCoder(S:String; const Delimited:string=''):string; var U4:UCS4String;     i: Cardinal; begin   Result :='';   U4 :=WideStringToUCS4String(VarToWideStr(s));   for i:=0 to Length(U4)-2 do //最后1位为字符串结束标志0     Result:=Result+ IntToHex(U4[i],8)+Delimited; end;

function BytesOf(const Val: AnsiString): TBytes; var   Len: Integer; begin   Len := Length(Val);   SetLength(Result, Len);   Move(Val[1], Result[0], Len); end;

function HexStrToDec(HexStr: AnsiString):AnsiString; //按每2位Hex字符转换为3位十进制数字字符串 var Len:Integer;     Abyte:Byte; begin   Result :='';   Len :=Length(HexStr);   if Odd(Len) then Dec(Len);   while Len>0 do   begin     //Result :=IntToStr(StrtoInt('$'+HexStr[Len-1]+ HexStr[Len]))+' '+Result ;     Abyte := StrtoInt('$'+HexStr[Len-1]+ HexStr[Len]);     Result :=Format('%.3d ',[Abyte])+Result ;         Dec(Len,2);   end;

end;

function BytesToHexStr(ABytes: TBytes; len: Integer): AnsiString; begin   SetLength(Result, len*2);   BinToHex(@ABytes[0], PAnsiChar(Result), len); end;

function HexStrToBytes(const HexStr: AnsiString): TBytes; var   Len,i,j: Integer; begin   Len := Length(HexStr);   if Odd(Len) then Dec(Len);   Len := Len div 2;   SetLength(Result, Len);   j:=1;   for  i:=0 to len-1 do     begin       Result[i] := StrToInt('$'+Hexstr[j]+ Hexstr[j+1]);       Inc(j,2);     end;  // Move(HexStr[1], Result[0], Len); end;

//机内码 转 Ansi(GB2312)字符,中文是>=$80的2个字节的值(每个字节高位都是1),英文和数字<$80 function CoderToAnsiStr(HexS: String;const Delimited:string=''):String; Var   bs: TBytes; begin   if Pos(' ',HexS)>0 then HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  bs :=HexStrToBytes(HexS);   Result :=PChar(bs);   SetLength(Result,Length(bs));  //不设置长度,有时会多一个符号 * end;

{function CoderToAnsiStr2(HexS: String;const Delimited:string=''):String; //这方法是纯中文的转换 Var   I,coder: Integer; begin   HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);

  I := Length(HexS);   while I >=4 do   begin     try       coder:=StrToInt('$'+HexS[I-3]+HexS[I-2]+HexS[I-1]+HexS[I]);       Result := Chr(coder shr 8) +Chr(coder mod 256)+Result;     except     end;     I := I - 4;   end; end; }

//机内码 转 unicode字符 function CoderToUnicodeStr(HexS: String;const Delimited:string=''):String; Var   bs: TBytes; begin   Result :='';   if Pos(' ',HexS)>0 then HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  bs :=HexStrToBytes(HexS);   Result :=PWideChar(bs);        //或者Result :=PUCS2Char(bs);   SetLength(Result,Length(bs));  //不设置长度,有时会多一个符号 *  end;

//机内码 转 unicode big endian字符 function CoderToUnicodeBigEndianStr(HexS: String;const Delimited:string=''):String; Var   bs: TBytes;   ws:WideString;   i:Cardinal; begin   Result :='';   if Pos(' ',HexS)>0 then HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  bs :=HexStrToBytes(HexS);   ws :=PWideChar(bs);   for i:=1 to length(WS) do     Result :=Result +widechar(Swap(word(WS[i])));

  SetLength(Result,Length(bs));  //不设置长度,有时会多一个符号 * end;

//机内码 转 unicode字符 function CoderToUtf32Str(HexS: String;const Delimited:string=''):String; Var   bs: TBytes;   U4:UCS4String;   ws:WideString;   Len:Integer ; begin     Result :='';   if Pos(' ',HexS)>0 then      HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then      HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  Len := Length(HexS)-(Length(HexS) mod 8);   HexS :=Copy(HexS,1,Len);       //忽略不足4个字节的内容

  bs :=HexStrToBytes(HexS);

 // Result :=PUCS4Char(bs); //编译不通过

  PUCS4Char(U4) :=@bs[0];    //UCS4String数组的指针 指向 bytes数组的第1个单元

    //注意:SetLength(var S; NewLength: Integer);   // 第2个参数是第1个参数类型的n倍,即第1个为宽字符,第2个为2,则:4*sizeof(宽字符)=8字节   SetLength(U4,(Length(bs) div 4)+1);   //加1的原因:参看UCS4StringToWideString函数

  ws:=UCS4StringToWideString(u4);

  Result :=ws;

  //以下释放内存,否则多次执行会报CPU错误,具体不清楚,应该是内存泄露(以下任何一单句都会报错,所以需要一起释放)   SetLength(bs,0);   SetLength(HexS,0);   SetLength(U4,0);   SetLength(ws,0); end;

//机内码 转 unicode big endian字符 function CoderToUtf32BigEndianStr(HexS: String;const Delimited:string=''):String; Var   bs: TBytes;   ws:WideString;   i:Cardinal; begin   Result :='';   if Pos(' ',HexS)>0 then HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  bs :=HexStrToBytes(HexS);   ws :=PWideChar(bs);   for i:=1 to length(WS) do     Result :=Result +widechar(Swap(word(WS[i])));

  SetLength(Result,Length(bs));  //不设置长度,有时会多一个符号 * end;

{function CoderToUnicodeStr2(HexS: String;const Delimited:string=''):String;   //此方法可以用,但觉得方法1通用一些的; Var   I: Integer; begin   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);

  I := Length(HexS);   I :=I - (I mod 4); //只取前面能被4整除的Hex机内码,比如BBCD12->BBCD,截断不正确的机内码   while I >=4 do   begin     try       Result :=WideChar(StrToInt('$'+HexS[I-3]+HexS[I-2]+HexS[I-1]+HexS[I]))+ Result;     except     end;     I := I - 4;   end; end; }

//机内码 转 UTF8字符 function CoderToUTF8Str(HexS: String;const Delimited:string=''):String; function Utf8Decode2( S: UTF8String; BytesCount:Cardinal): WideString;     //重写Utf8Decode,以便utf8机内码不完整时能忽略最后不完整字串 var   L: Integer;   Temp: WideString; begin   Result := '';   Temp :='';

  if S = '' then Exit;

 // showmessage('字节数:'+inttostr(BytesCount));  //显示字节数

  repeat     SetLength(Temp, BytesCount);

    L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PChar(S), BytesCount);     if L > 0 then       SetLength(Temp, L-1)     else       S := Copy(S,1,Length(s)-1);   until  (L>0) or  (Length(S)<1);   Result := Temp; end;

Var   bs: TBytes; begin   if Pos(' ',HexS)>0 then HexS :=StringReplace(HexS,' ','',[rfReplaceAll]);   //去空格   if Delimited<>'' then HexS :=StringReplace(HexS,Delimited,'',[rfReplaceAll]);  //去分隔字符串

  bs :=HexStrToBytes(HexS);

  Result :=Utf8Decode2(PChar(bs),length(bs)); end;

 

---------编码转换------------///

/--------BinToHexStr Begin-------- // function  BinFileToHexStr(BinFileName:string):string; var   BinaryStream: TMemoryStream; begin   BinaryStream := TMemoryStream.Create;   BinaryStream.LoadFromFile(BinFileName);   try     if BinaryStream.Size > 0 then     begin       //Result := StrAlloc(BinaryStream.Size*2);       //BinToHex(BinaryStream.Memory,Result,BinaryStream.Size);       SetLength(Result, BinaryStream.Size * 2);    //很重要,需要设置长度才可以的,因为要用成pchar       BinToHex(BinaryStream.Memory,PChar(Result),BinaryStream.Size);     end;   finally     BinaryStream.Free;   end; end;

function  HexStrToBinFile(HexStr:string;BinFileName:string):Boolean; var   BinaryStream: TMemoryStream; begin   Result :=False;   BinaryStream := TMemoryStream.Create;   try     BinaryStream.Size := Length(HexStr) div 2;     if BinaryStream.Size > 0 then     begin       HexToBin(PAnsiChar(HexStr), BinaryStream.Memory, BinaryStream.Size);       BinaryStream.SaveToFile(BinFileName);       Result :=True;     end;   finally     BinaryStream.Free;   end; end;

/--------BinToHexStr End-------- //

 /--------流转换Begin------- // function StreamToBytes(aStream:TStream):TBytes; begin  // aStream := TMemoryStream.Create;  //此处,不需要初始化流   try     SetLength(Result, aStream.Size);     aStream.Position := 0;     aStream.Read(Result[0], aStream.Size);   finally     aStream.Free;   end; end;

 //使用Stream前,需要Stream.Position := 0; 否则,读取不到内容 function BytesToStream(aBytes:TBytes):TStream; var   aStream: TStream; begin   aStream := TMemoryStream.Create;   try     aStream.Write(aBytes[0],length(aBytes));     aStream.Position := 0;     result :=aStream;   finally     //aStream.Free;  //此处,不可释放   end; end;

function StreamToHexStr(aStream:TStringStream):string; var   Len: Integer; begin   aStream.Position :=0;   Len :=aStream.size;   Result :='';   SetLength(Result, len*2);   BinToHex(PAnsiChar(aStream.DataString), PAnsiChar(Result), len);   //BinToHex(PAnsiChar(aStream), PAnsiChar(Result), len);     //用stream不成功  // BinToHex(@aStream, PAnsiChar(Result), len);                //用stream不成功 end;

function StreamToHexStr(aStream:TMemoryStream):string; var   Len: Integer; begin   aStream.Position :=0;   Len :=aStream.size;   Result :='';   SetLength(Result, len*2);

  BinToHex(aStream.Memory, PAnsiChar(Result), len); end;

function StreamToHexStr(aStream:TBytesStream):string; var   Len: Integer; begin   aStream.Position :=0;   Len :=aStream.size;   Result :='';   SetLength(Result, len*2);

  BinToHex(aStream.Memory, PAnsiChar(Result), len); end;  /--------流转换End------- //

end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值