TFileStream 写数据到下一行

TFileStream write data to next line

我正在操作 TFileStream,我想将数据写入下一行。

以下代码重写了之前的代码...

我该怎么做才能换行并让它在那里写入新行?

function TParserSkyecc.GenerateHTMLFile(pathHtml,out1,out2,out3,out4,out5 : String) : Boolean;
var FS: TFileStream;
begin
  FS := TFileStream.Create(pathHtml+'\filename.txt',fmCreate or fmOpenWrite or fmShareDenyNone);
  try
  FS.Seek(0,soFromBeginning);
    FS.WriteBuffer(Pointer(AnsiString(out1))^,Length(out1));
    FS.WriteBuffer(Pointer(AnsiString(out2))^,Length(out2));
    FS.WriteBuffer(Pointer(AnsiString(out3))^,Length(out3));
    FS.WriteBuffer(Pointer(AnsiString(out4))^,Length(out4));
    FS.WriteBuffer(Pointer(AnsiString(out5))^,Length(out5));
  finally
    FS.Free;
  end;
end;
uses System.Classes, System.SysUtils, System.IOUtils;

VAR pathHtml : STRING;

PROCEDURE Test(CONST TXT : STRING);
  VAR
    FS  : TStream;
    N   : TFileName;
    B   : TBytes;

  BEGIN
    N:=TPath.Combine(pathHtml,'filename.txt');
    IF NOT TFile.Exists(N) THEN
      FS:=TFileStream.Create(N,fmCreate OR fmShareDenyNone)
    ELSE BEGIN
      FS:=TFileStream.Create(N,fmOpenWrite OR fmShareDenyNone);
      FS.Position:=FS.Size
    END;
    TRY
      B:=TEncoding.ANSI.GetBytes(TXT);
      FS.WriteBuffer(B,LENGTH(B))
    FINALLY
      FS.Free
    END
  END;

实施意见:

  1. 使用TPath.Combine组合目录和文件名
  2. 使用 TEncoding.ANSI.GetBytes 将 UNICODE 字符串转换为 ANSI。您在上面使用的版本有问题,因为与 UNICODE 字符串等效的 AnsiString 的长度可能与 UNICODE 字符串不同,f.ex。当您的国家字符在 UNICODE 中编码为一对,但在 AnsiString 中编码为单个字节时,您可能最终(试图)写入比 AnsiString 转换产生的字节更多的字节。
  3. 小心使用 AnsiString(和 TEncoding.ANSI),因为它取决于程序所在计算机的 language/region 设置 运行。

如果汤姆在评论中说的话: Asker 希望将字符串放在文件中的不同行上。 是真的,那么就相当简单了。只需替换行

FS.WriteBuffer(Pointer(AnsiString(out1))^,Length(out1));
FS.WriteBuffer(Pointer(AnsiString(out2))^,Length(out2));
FS.WriteBuffer(Pointer(AnsiString(out3))^,Length(out3));
FS.WriteBuffer(Pointer(AnsiString(out4))^,Length(out4));
FS.WriteBuffer(Pointer(AnsiString(out5))^,Length(out5));

out1:=out1+#13#10; out2:=out2+#13#10; out3:=out3+#13#10;out4:=out4+#13#10; out5:=out5+#13#10;
FS.WriteBuffer(Pointer(AnsiString(out1))^,Length(out1));
FS.WriteBuffer(Pointer(AnsiString(out2))^,Length(out2));
FS.WriteBuffer(Pointer(AnsiString(out3))^,Length(out3));
FS.WriteBuffer(Pointer(AnsiString(out4))^,Length(out4));
FS.WriteBuffer(Pointer(AnsiString(out5))^,Length(out5));

在每行后面附加一个 CR/LF。

一种更简单的编写方法是使用 TStreamWriter instead of TFileStream directly. TStreamWriter takes a TEncoding in its constructor, and has a WriteLine() 方法。例如:

function TParserSkyecc.GenerateHTMLFile(pathHtml,out1,out2,out3,out4,out5 : String) : Boolean;
var
  Filename: string;
  Writer: TStreamWriter;
begin
  Result := False;
  try
    Filename := IncludeTrailingPathDelimiter(pathHtml) + 'filename.txt'; // or: TPath.Combine(pathHtml, 'filename.txt')
    Writer := TStreamWiter.Create(Filename, False, TEncoding.ANSI);
    try
      Writer.WriteLine(out1);
      Writer.WriteLine(out2);
      Writer.WriteLine(out3);
      Writer.WriteLine(out4);
      Writer.WriteLine(out5);
      Writer.Flush;
      Result := True;
    finally
      Writer.Free;
    end;
  except
  end;
end;

或者,您可以使用 TStringList 代替:

function TParserSkyecc.GenerateHTMLFile(pathHtml,out1,out2,out3,out4,out5 : String) : Boolean;
var
  Filename: string;
  SL: TStringList;
begin
  Result := False;
  try
    Filename := IncludeTrailingPathDelimiter(pathHtml) + 'filename.txt'; // or: TPath.Combine(pathHtml, 'filename.txt')
    SL := TStringList.Create;
    try
      SL.Add(out1);
      SL.Add(out2);
      SL.Add(out3);
      SL.Add(out4);
      SL.Add(out5);
      SL.SaveToFile(Filename, TEncoding.ANSI);
      Result := True;
    finally
      SL.Free;
    end;
  except
  end;
end;