来看一下吧,Delphi7中怎么一行一行读取Unicode文件(求助)

bsbnike 2005-03-19 07:59:55
我要实现的功能是只能一行一行的读取unicode文件,假设我现在已经有了一个aaa.txt的unicode文件。
procedure TForm1.TButton1Click(Sender: TObject);

var pf:Textfile;
str1:widestring;
begin
Assignfile(pf,'D:\aaa.txt');
Reset(pf);
while not eof(pf) do
begin
readln(pf,str1);
//Tmemo1.Lines.add(str1);
TRichEdit1.Lines.add(str1);
//showmessage(str1);
end;
closefile(pf);
end;
显然这是不行的。因为delphi的VCL对unicode的支持不好。
然后我又在这个网站上面找了很多帖子,发现有个Tntunicode的第3方控件。下载下来装好后。把控件换成了第三方控件,发现还是不能读取,显示的是乱码。
我想问题可能是出在Readln这个函数上,于是就改用流来读文件。代码如下:
procedure TForm1.TntButton1Click(Sender: TObject);//Tntbutton是第三方控件
var
FileStrm: TFileStream;
FileContent: WideString;
ContentSize: Integer;
begin
FileStrm := TFileStream.Create('D:\aaa.txt', fmOpenRead);
ContentSize := FileStrm.Size - 2;
SetLength(FileContent, ContentSize div 2);
FileStrm.Position := 2;//跳过Unicode标志
FileStrm.Read(FileContent[1], ContentSize);
TntRichedit1.Lines.Text := FileContent;//TntRichedit也是第三方控件
FileStrm.Free;
end;
结果就能够正常显示了。
但我是要一行一行的读取文件啊。Readln是没指望了。我想只有用流才能行了,请高手指点用流来读文件有什么函数可以一行一行的读啊?
...全文
871 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
tigerjacky 2005-04-08
  • 打赏
  • 举报
回复
MARK
bsbnike 2005-03-25
  • 打赏
  • 举报
回复
感谢大家的参与,虽然大家的解答与我的设想不太一样,但是给我了很多借鉴,最终我还是自己解决了问题。我的总结是在delphi里面要读取unicode文件,一定不能用readln函数,而要用流来处理,至于要一行一行的读取文件可以先把每一行内容存在一个Tstring里面,通过循环来处理
王集鹄 2005-03-21
  • 打赏
  • 举报
回复
// Read(W[1], Length(S));
Read(W[1], Length(W) * SizeOf(WideChar)); //<<<<空间不够,改成这样
vStringList.Text := W;
xuancaoer 2005-03-21
  • 打赏
  • 举报
回复
我不知道unicode有什么特点,也不知道多难
var
s:TStringList;
begin
s := TStringList.Create();
s.LoadFromFile('d:\a.txt');
//for i:=0 to s.count-1 do
Memo1.Text:=s.Strings[i];
end;
循环控制那些自己试下
merkey2002 2005-03-21
  • 打赏
  • 举报
回复
procedure TForm1.Button2Click(Sender: TObject);
var
F:TFileStream;
S:WideString;
I:Integer;
const
FileName='a.txt';
begin
F:=TFileStream.Create(FileName,fmOpenRead);
I:=F.Size;
SetLength(S,I div 2);
F.Read(S[1],I);
F.Free;
Delete(S,1,1);
Memo1.Text:=S;
end;
//文件流方式读取文件(unicode)
cctv6012cn 2005-03-20
  • 打赏
  • 举报
回复
学习.........
bsbnike 2005-03-20
  • 打赏
  • 举报
回复
zswang(伴水清清)(专家门诊清洁工)

再次测试,
procedure TForm1.Button2Click(Sender: TObject);
var
S: string;
W: WideString;
vStringList: TStringList;
I: Integer;

begin
//取
vStringList := TStringList.Create;
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;
vStringList.Text := W;
for I := 0 to vStringList.Count - 1 do
RichEdit1.Lines.Add(vStringList[I]);
vStringList.Free;
finally
Free;
end;
end;

显示的还是乱码,不知道是什么问题了。请指点。
我的Temp.txt的unicode文件内容为

第一行
第二行
第三行

运行时显示的乱码是
第????????????
王集鹄 2005-03-20
  • 打赏
  • 举报
回复
……
用“取”的代码不就得了
//...
Read(W[1], Length(S));
Memo2.Text := W; //只是作为输出测试用
//...
var
vStringList: TStringList;
I: Integer;
begin
vStringList := TStringList.Create;
{ TODO : 取 }
vStringList.Text := W;
for I := 0 to vStringList.Count - 1 do
RichEdit1.Lines.Add(vStringList[I]);
vStringList.Free;
end;
bsbnike 2005-03-20
  • 打赏
  • 举报
回复
zswang(伴水清清)(专家门诊清洁工)
谢谢你的参与!
你的代码能通过编译,但是没有达到我的目的。我要求的是要一行一行的读取Unicode文件。并且这个unicode文件已经是存在的,不需要重新创建。
王集鹄 2005-03-19
  • 打赏
  • 举报
回复
//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;
forgot2000 2005-03-19
  • 打赏
  • 举报
回复
手头没有Delphi,不能帮你测试,不过应该能够实现。给你个想法:判断WideString的长度,先写长度为1的ASCII字符,再写长度为2的Unicode字符,你先试试,偶不知道还有没有长度为4的Unicode字符。

5,939

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧