Delphi TStringlist未加载Google联系人文件

Delphi TStringlist未加载Google联系人文件,delphi,delphi-2007,tstringlist,Delphi,Delphi 2007,Tstringlist,我正在尝试使用Stringlist加载由Google Contacts生成的CSV文件。当我在像Sublime text这样的文本编辑器中打开这个文件时,我可以正确地看到75行的内容。这是Google联系人文件中的一个示例: Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initi

我正在尝试使用Stringlist加载由Google Contacts生成的CSV文件。当我在像Sublime text这样的文本编辑器中打开这个文件时,我可以正确地看到75行的内容。这是Google联系人文件中的一个示例:

Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Group Membership,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Phone 3 - Type,Phone 3 - Value
H,H,,,,,,,,,,,,,   1-01-01,,,,,,,,,,,,* My Contacts ::: Importado 01/02/16,,,,,,
H - ?,H,-,?,,,,,,,,,,,   1-01-01,,,,,,,,,,,,* My Contacts ::: Importado 01/02/16,Mobile,031-863-64393,,,,
H - ?,H,-,?,,,,,,,,,,,,,,,,,,,,,,,* My Contacts ::: Importado 01/02/16,Mobile,031-986-364393,,,,
但是,当我尝试使用Stringlist加载同一文件时,我在Stringlist.text属性中看到的是:

“ÿþN”$D$A

这是我的密码:

procedure Tform1.loadfile;
var sl : tstringlist;
begin
sl := tstringlist.create;
sl.loadfromfile('c:\google.csv');
showmessage('lines : '+inttostr(sl.count)+' / text : '+ sl.text);
end;
这是我得到的结果:

“1/”D$A”

这里发生了什么


谢谢

根据您提供的十六进制转储,BOM表表明您的文件是使用UTF-16LE编码的。在我看来,你面前有几个选择:

切换到Unicode并使用TnT Unicode控件处理此文件。 以字节数组的形式读取文件。转换为ANSI,然后继续使用ANSI编码的文本。显然,您将丢失ANSI代码页无法编码的任何字符的信息。一种廉价的方法是将文件作为字节数组读取。将前两个字节(BOM表)后面的内容复制到一个宽字符串中。然后将该宽字符串指定给ANSI字符串。 将您的程序移植到Delphi 2007之后的Unicode版本,并在本地使用Unicode。
我怀疑你对文本编码不是很熟悉。如果你是的话,我想你自己就能回答这个问题了。这很好,但我敦促你花时间好好了解这个问题。如果你现在就急于编码,在没有良好的基础之前,你肯定会把它搞得一团糟。我们已经看到很多人犯同样的错误。请不要添加到文本编码伤亡人员列表中。

感谢David的信息,我可以使用下面的功能完成任务;因为Delphi2007不支持unicode,所以需要第三方函数来实现

procedure loadUnicodeFile( const filename: String; strings: TStringList);
Procedure SwapWideChars( p: PWideChar );
Begin
While p^ <> #0000 Do Begin
// p^ := Swap( p^ ); //<<< D3
p^ := WideChar( Swap( Word(p^)));
Inc( p );
End; { While }
End; { SwapWideChars }

Var
ms: TMemoryStream;
wc: WideChar;
pWc: PWideChar;
Begin
ms:= TMemoryStream.Create;
try
ms.LoadFromFile( filename );
ms.Seek( 0, soFromend );
wc := #0000;
ms.Write( wc, sizeof(wc));

pWC := ms.Memory;
If pWc^ = #$FEFF Then // normal byte order mark
Inc(pWc)
Else If pWc^ = #$FFFE Then Begin // byte order is big-endian
SwapWideChars( pWc );
Inc( pWc );
End { If }
Else; // no byte order mark
strings.Text := WideChartoString( pWc );
finally
ms.free;
end;
End;

那就行了。但如果是我,我会将文件加载到十六进制编辑器中,并查看十六进制转储。你手头没有十六进制编辑器吗?你懂文本编码吗?升华会告诉你编码是什么吗?不要再浪费时间了;请获取可以以十六进制格式显示文件的查看器。然后拍摄屏幕截图,然后只上传图像的前几行。或者复制显示文本的前几行,并将其放在上面的问题中。UTF-8编码文件的前三个字节将是EF BB BF。在stringlist.text的第一次粘贴中:“ÿþN”$D$A开头有一个撇号。这也是文件的一部分吗?这些信息是问题的关键。请把它包括在问题中。带着编辑。作为一个迄今为止有50多个问题的人,我觉得你现在应该知道这一点。请通读:。它将解释很多关于编码的内容。