问题: 文本文件的编码和读取问题。 ( 积分: 200 )
分类: 系统相关
来自: chenglh, 时间: 2005-08-01 17:29:00, ID: 3152966
请问各位大侠:
一个文本文件用UltraEdit、记事本打开都能正常显示。可是我用AssignFile和Readln读取读出来的是乱码。我发现它是个unicode格式的文本文件。请问有没有自动能判断文本文件编码的函数或者控件可以读取文件中的文本行?谢谢了
来自: czcn, 时间: 2005-08-02 8:30:21, ID: 3153314
用memo1.lines.loadfromfile()打开就OK了.
来自: chenglh, 时间: 2005-08-02 8:43:29, ID: 3153328
我试了,好像不行。
昨天查了离线大富翁,知道.net Framework可以很容易的做到,用Reader和Encoding类就可以了,非常简单,在win32程序下怎么做呢?
来自: smokingroom, 时间: 2005-08-02 8:55:43, ID: 3153342
Delphi的Edit/RichEdit不支持对Unicode编码的文本文件的直接处理。需要自己写代码处理。可以分为几步:一、取该文件的前两个字节,如果该两个字节为$FFFE,则该文本为Unicode编码;若为$FEFF,则为Unicode big endian编码。二、跳过前两个字节,读取Unicode文本,调用WideCharToMultiByte函数转成GBK编码的文本。
来自: chenglh, 时间: 2005-08-02 10:50:02, ID: 3153506
非常感谢smokingroom,已搞定Unicode的情况。
如果要是其他的编码呢?比如utf-8,日文之类该如何处理?
我现在要做一个读取符合标准接口文本文件,这个文本可能是gb编码或者或者其他的编码,
有没有像Reader+encoding类这样可以直接操作文本文件的类?
来自: goddy, 时间: 2005-08-02 10:53:17, ID: 3153513
文件前面加一个字节"FF" 就不会乱码了,你用debug试一下
来自: chenglh, 时间: 2005-08-02 11:19:21, ID: 3153544
To goddy:
我现在的文件的第一个字节本身已经是$FF的。
来自: smokingroom, 时间: 2005-08-02 15:00:56, ID: 3153865
UTF-8的处理与Unicode差不多,UTF-8的前两个字节为$EFBB(以一个字Word的形式读取),需要跳过三个字节再读取UTF-8文本,读取后的文本先经Utf8Decode函数处理,处理结果再经WideCharToMultiByte函数处理即可.
来自: smokingroom, 时间: 2005-08-02 15:05:54, ID: 3153877
.NET的StreamReader+Encoding确实很容易处理这种情况. 用于Delphi中的类似Class好像没有.
来自: chenglh, 时间: 2005-08-04 17:31:57, ID: 3154950
再谢smokingroom
utf8怎么又变成偏移三个byte呢?(我需要改代码来包括这种情况了)
这样是不是要单独处理不同的codebase? 请问有没有这样一个表格,这个表格说明偏移量,头字节值和编码的对应关系?这样我就可以很容易地自己写一个函数或者类了,和.net framework里的一样。
来自: smokingroom, 时间: 2005-08-19 9:37:17, ID: 3156498
Notepad(记事本)只支持四种格式:ANSI/Unicode/Unicode big endian/UFT-8,所以,你只要支持这四种格式就可以了。
ANSI: 无格式定义;
Unicode: 前两个字节为FFFE;
Unicode big endian: 前两字节为FEFF;
UTF-8: 前两字节为EFBB;
以下是我的一个软件中的处理代码,你可以参考一下:
type
TTextFormat=(tfAnsi,tfUnicode,tfUnicodeBigEndian,tfUtf8);
const
TextFormatFlag:array[tfAnsi..tfUtf8] of word=($0000,$FFFE,$FEFF,$EFBB);
function WordLoHiExchange(w:Word):Word;register;
asm
XCHG AL, AH
end;
{ TextFormat返回文本编码类型,sText未经处理的文本 }
procedure ReadTextFile(const FileName: string;
var TextFormat: TTextFormat; var sText:string);
var
w:Word;
b:Byte;
begin
with TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone) do
try
Read(w,2);
w:=WordLoHiExchange(w);//因为是以Word数据类型读取,故高低字节互换
if w = TextFormatFlag[tfUnicode] then
TextFormat:= tfUnicode
else if w = TextFormatFlag[tfUnicodeBigEndian] then
TextFormat:= tfUnicodeBigEndian
else if w = TextFormatFlag[tfUtf8] then
begin
Read(b,1);//这里要注意一下,UFT-8必须要跳过三个字节。
TextFormat:=tfUtf8;
end else
begin
TextFormat:=tfANSI;
Position:=0;
end;
SetLength(sText,Size-Position);
ReadBuffer(sText[1],Size-Position);
finally
Free;
end;
end;
来自: chenglh, 时间: 2005-08-05 8:54:47, ID: 3157008
notePad也支持4种?这样我就放心了,多谢你的代码。
得分大富翁: czcn-10,goddy-10,smokingroom-180,