在DLEPHI中读取unicode文件

    如今,unicode编码已经逐渐成为一种趋势,越来越多的被应用到实际项目之中。而DELPHI中,无论是D7还是最新的D2005,在win32程序中,VCL组件依然不支持unicode编码。这就需要我们这些程序员动脑子了。

    (一)你可以使用TntUnicodeControls组件。

   下载地址:http://download.tntware.com/delphi_unicode_controls/TntUnicodeControls.zip

    (二)自己编写读取的过程

     下面平时使用的几个这样的函数整理如下:

        实现unicode文件的读取,unicode->Ansi

 function GetFileText(const FileName: string): string;
var
  hFile: DWORD;
  iSize: DWORD;
  sTemp: string;
begin
 // 打开文件
  hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 // 文件大小
  iSize := GetFileSize(hFile, nil);
 // 申请内存
  SetLength(sTemp, iSize + 2);
 // 读入文件
  ReadFile(hFile, sTemp[1], iSize, iSize, nil);
 // 关闭文件
  CloseHandle(hFile);
 // 置结束符
  sTemp[iSize + 1] := #0;
  sTemp[iSize + 2] := #0;
 // 编码格式
  if (sTemp[1] = #$FF) and (sTemp[2] = #$FE) then // UNICODE
  begin
   // 申请内存
    SetLength(Result, iSize);
   // 转换编码
    WideCharToMultiByte(CP_ACP, 0, PWideChar(@sTemp[3]), -1, @Result[1], iSize, nil, nil);
  end else
    Result := sTemp;
   // 去掉多余字符
  Result := string(PChar(Result));
end;


//Unicode存、取
procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  W: WideString;
begin
  if Memo1.Text = '' then Exit;
  //存
  with TMemoryStream.Create do try
    S := #$FF#$FE;
    Write(S[1], Length(S));
    W := Memo1.Text;
    Write(W[1], Length(W) * SizeOf(WideChar));
    Position := 0;
    SaveToFile('c:/temp/temp.txt');
  finally
    Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: string;
  W: WideString;
begin
  //取
  if not FileExists('c:/temp/temp.txt') then Exit;
  with TMemoryStream.Create do try
    LoadFromFile('c:/temp/temp.txt');
    if Size < 4 then Exit;
    SetLength(S, 2);
    Read(S[1], Length(S));
    if Copy(S, 1, 2) <> #$FF#$FE then Exit;
    SetLength(W, (Size - 2) div SizeOf(WideChar));
    Read(W[1], Length(S));
    Memo2.Text := W;
  finally
    Free;
  end;
end;

//Utf8存、取
procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
begin
  //存
  with TMemoryStream.Create do try
    S := #$EF#$BB#$BF;
    Write(S[1], Length(S));
    S := AnsiToUtf8(Memo1.Text);
    Write(S[1], Length(S));
    Position := 0;
    SaveToFile('c:/temp/temp.txt');
  finally
    Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: string;
begin
  //取
  if not FileExists('c:/temp/temp.txt') then Exit;
  with TMemoryStream.Create do try
    LoadFromFile('c:/temp/temp.txt');
    SetLength(S, Size);
    Read(S[1], Length(S));
    if Copy(S, 1, 3) <> #$EF#$BB#$BF then Exit;
    Memo2.Text := Utf8ToAnsi(Copy(S, 4, MaxInt));
  finally
    Free;
  end;
end;

// Unicode String --> ANSI string 中文格式编码
// eg. 0031003200610062554A94B1658C --> 12ab啊钱斌
// OK! 20030208 QB
function UnicodeToAnsi(sStr:String):String;
var
  sStr1: string;
  wStr: WideString;
  psStr1,psStr: PChar;
  iUnicode,i,len: Integer;
begin
  sStr1:='';
  // 为sStr1申请200字节的空间
  for i:=1 to 200 do sStr1:=sStr1+'-';
  psStr1:=PChar(sStr1);
  len:=Length(sStr);
  i:=1;
  while i<=len do
  begin
    // '554a' --> chr(0x55)+chr(0x4a)
    psStr:=PChar(sStr)+i-1;
    HexToBin(psStr, psStr1, 2);
    // chr(0x55)+chr(0x4a) --> 21834
    iUnicode:=ord(sStr1[1])*256+ord(sStr1[2]);
    // 21834 --> '啊'
    wStr:=wStr+WideChar(iUnicode);
    i:=i+4;
  end;
  Result:=String(wStr);
end;




// ANSI String --> Unicode string 中文格式编码
// eg. 12ab啊钱斌 --> 0031003200610062554A94B1658C
// OK! 20010710 QB
// function AnsiToUnicode(var s:WideString):String;
function AnsiToUnicode(sStr:String):String;
var
  i,len: Integer;
  cur: Integer;
  t: String;
  s: WideString;
begin
  // WideString('1啊') --> '1啊'
  s:= WideString(sStr);
  Result:='';
  // Length(WideString('1啊')) = 2 !!!
  len:=Length(s);
  i:=1;
  while i<=len do
  begin
    // Unicode of '啊' --> 21834
    cur:=ord(s[i]);
    // 21834 --> '554a'
    FmtStr(t,'%4.4X',[cur]); // ???? <-- 钱勤
    Result:=Result+t;
    inc(i);
  end;
end;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值