我要实现的功能是只能一行一行的读取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是没指望了。我想只有用流才能行了,请高手指点用流来读文件有什么函数可以一行一行的读啊?

解决方案 »

  1.   

    手头没有Delphi,不能帮你测试,不过应该能够实现。给你个想法:判断WideString的长度,先写长度为1的ASCII字符,再写长度为2的Unicode字符,你先试试,偶不知道还有没有长度为4的Unicode字符。
      

  2.   

    //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;
      

  3.   

    zswang(伴水清清)(专家门诊清洁工) 
    谢谢你的参与!
    你的代码能通过编译,但是没有达到我的目的。我要求的是要一行一行的读取Unicode文件。并且这个unicode文件已经是存在的,不需要重新创建。
      

  4.   

    ……
    用“取”的代码不就得了
    //...
        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;
      

  5.   

    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文件内容为第一行
    第二行
    第三行运行时显示的乱码是
    第????????????
      

  6.   

    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)
      

  7.   

    我不知道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;
    循环控制那些自己试下
      

  8.   

    //  Read(W[1], Length(S));
        Read(W[1], Length(W) * SizeOf(WideChar)); //<<<<空间不够,改成这样
        vStringList.Text := W;
      

  9.   

    感谢大家的参与,虽然大家的解答与我的设想不太一样,但是给我了很多借鉴,最终我还是自己解决了问题。我的总结是在delphi里面要读取unicode文件,一定不能用readln函数,而要用流来处理,至于要一行一行的读取文件可以先把每一行内容存在一个Tstring里面,通过循环来处理