乱码问题:一文本文件,用写字板打开中文显示为乱码,用记事本打开中文显示正常,所以估记该文件编码为utf8类型,那么如何用stringlist加载该文本文件后,读

  • 主题发起人 主题发起人 wyxriver
  • 开始时间 开始时间
W

wyxriver

Unregistered / Unconfirmed
GUEST, unregistred user!
乱码问题:一文本文件,用写字板打开中文显示为乱码,用记事本打开中文显示正常,所以估记该文件编码为utf8类型,那么如何用stringlist加载该文本文件后,读出正确的内容并修改后再用savetofile保存呢? ( 积分: 250 )<br />现在用stringlist.loadfromfile该文件后,发现只要有汉字的地方就是乱码,无法修改,如何才能让其显示正常?另外显示正常后,我还要修改某些项的值,然后再保存为同原格式一样的格式。

我用的代码如下:
var
s:tstringlist;
x:integer;
begin
s:=tstringlist.create;
s.loadfromfile('d:/a.txt');
for x:=1 to s.count do begin
showmessage(s[x-1]);
end;
end;

现在我仍希望用如上的方法读写该UTF8文件,只是如何对付其显示为乱码的问题呢?
 
创建另一个 StrList2: TSstringList;
把前面不需要改的行 Add 到该 StrList2
把需要修改的行读出来,修改,Add添加到 StrList2
最后把剩余的行读出来,添加到 StrList2后面。
保存 StrList2.SaveToFile('d:/a.txt');
 
逐行读入一个str啦
然后Utf8ToAnsi(str)

//冰力不足土制函数BLWriteText 写入文本
procedure BLWriteText(TextFileName: string; Str: string);
var
f: Textfile;
begin
Assignfile(f, TextFileName);
if FileExists(TextFileName) = false then
begin
ReWrite(f);
Closefile(f);
end;
Append(f);
Writeln(f, Str);
Closefile(f);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Str: String;
sl: TStringlist;
i: integer;
begin
sl := TStringlist.Create;
sl.LoadFromFile('d:/a.txt');
for i := 0 to sl.Count - 1 do
begin
Str := Str + sl + #13#10;
end;
sl.Free;
Str := Utf8ToAnsi(Str);
BLWriteText('d:/b.txt', Str);
end;
 
只要进行相应的编码转换就可以了。

TStrings的LoadFromFile不能正确加载包含#0字符的文件,建议不要用TStrings对像进行Unicode和Utf-8编码的文件进读写。

读文件
procedure TForm1.Button1Click(Sender: TObject);
var

str:string;
wstr:Widestring;
fs:TFileStream;
Len:integer;
begin
fs:= TfileStream.Create('C:/1.txt',fmShareDenyNone or fmOpenRead );
try
Len:= fs.Size;
setLength(str,3);
fs.Read(str[1],3);
if copy(str,1,2) = #$FF#$FE then
begin
//Unicode编码=====================
Wstr:='';
fs.Position:=2;
setLength(str,Len-2);
fs.Read(str[1],Len-2);
if (Length(str) >= 2) then
begin
setLength(wstr,Length(str)div 2 + Length(str)mod 2);
Move(str[1],wstr[1],Length(str));
end;
Memo1.Text := Wstr;

exit;
end else if str = #$EF#$BB#$BF then
begin
//UTF8编码========================
setLength(str,Len-3);
fs.Read(str[1],Len-3);
Memo1.Text := Utf8ToAnsi(str);

exit;

end;
//ANSI编码============================
fs.Position:=0;
setLength(str,Len);
fs.Read(str[1],Len);
memo1.Text := str;
finally
fs.Free;
end;
end;

写文件
procedure TForm1.Button2Click(Sender: TObject);
var
str:string;
wstr:Widestring;
utf8:Utf8string;
fs:TFileStream;
i,Len:integer;
begin
fs:= TfileStream.Create('C:/1.txt',fmShareDenyNone or fmOpenReadwrite );
try
setLength(str,3);
fs.Read(str[1],3);
if copy(str,1,2) = #$FF#$FE then
begin
//Unicode编码=====================
fs.Position := 2;
wstr:= memo1.text;
if wstr <> '' then
fs.Write(wstr[1],Length(wstr)*sizeof(widechar));
fs.Size := fs.Position;
exit;
end else if str = #$EF#$BB#$BF then
begin
//UTF8编码========================
fs.Position := 3;
utf8:= Ansitoutf8(memo1.Text);
if utf8 <> '' then
fs.Write(utf8[1],Length(utf8));
fs.Size := fs.Position;
exit;
end;
//ANSI编码============================
fs.Position:=0;
if memo1.Text <> '' then
fs.Write(memo1.Text[1],Length(memo1.Text));
fs.Size := fs.Position;
finally
fs.Free;
end;
end;
 
多謝各位幫忙,又有新的發現,打開該 文本文件,發現第一行為:
<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>
這應該是UTF-8編碼的XML文件吧,對這種文件有沒有更好的更直接的控件可以直接操作它呢?比如說有沒有類似於tstringlist的控件,可以直接打開它,然後可以編輯其中某行,然後再以原格式保存它呢?
 
TXMLDocument
 
用Tnt控件,有个TTntStringList,支持Unicode,跟TStringList一样的用法,超级简单

------------------------
www.waibaoinfo.com
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,TntClasses;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
x,y:Integer;
s:TtntStringlist;
begin
s:=TtntStringList.Create;
s.loadFromFile('d:/aaa.txt');
for x:=1 to s.count do showmessage(s[x-1]);


end;

end.
 
经试验,用tnttstringlist可以正常读出,可是用它的savetofile保存后文件编码改变,不能再被原来其应用程式打开。
 
对TXMLDocument 不是太熟,看了一下例程,感觉不太喜欢这种方式,请问有没有不用TXMLDocument 也能读出并处理这个xml格式的文档。因为我只是需要替换中间的某个值而已
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
TForm1 = class(TForm)
XMLDocument1: TXMLDocument;
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);


private
{ Private declarations }
public
{ Public declarations }

function GetXmlTree(nNode: IXMLNode): string;

end;

var
Form1: TForm1;


implementation

{$R *.dfm}

function TForm1.GetXmlTree(nNode: IXMLNode): string;
var
i, j: integer;
s:string;
begin
for i:=0 to nNode.ChildNodes.Count-1 do
begin
s :=nNode.ChildNodes.Nodes.NodeName;
showmessage(s);
for j:=0 to nNode.ChildNodes.AttributeNodes.Count-1 do
begin
s := s + ' '+ nNode.ChildNodes.AttributeNodes[j].NodeName;
s := s + '=&quot;'+ nNode.ChildNodes.AttributeNodes[j].NodeValue +'&quot;';
end;
s := s + '>';
if nNode.ChildNodes.Nodes.IsTextElement then
s := s + nNode.ChildNodes.Nodes.Text;
if nNode.HasChildNodes and not nNode.ChildNodes.Nodes.IsTextElement then
begin
s := s + #13 + #10;
GetXmlTree(nNode.ChildNodes.Nodes);
end;
s := s + '</'+ nNode.ChildNodes.Nodes.NodeName +'>' + #13 + #10;
end;
result := s;
end;




procedure TForm1.Button2Click(Sender: TObject);
var
xml: TXMLDocument;
str:string;
begin
Xml := TXMLDocument.Create(self);
Xml.FileName := 'd:/2.prproj';
Xml.Active:=true;
str :='';
str := GetXmlTree(Xml.ChildNodes.FindNode('PremiereData'));
Memo1.Lines.Add(str);
application.ProcessMessages;
Xml.Free;
end;



end.
 
问题解决
 

Similar threads

回复
0
查看
1K
不得闲
回复
0
查看
804
不得闲
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部