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;
实施意见:
- 使用TPath.Combine组合目录和文件名
- 使用 TEncoding.ANSI.GetBytes 将 UNICODE 字符串转换为 ANSI。您在上面使用的版本有问题,因为与 UNICODE 字符串等效的 AnsiString 的长度可能与 UNICODE 字符串不同,f.ex。当您的国家字符在 UNICODE 中编码为一对,但在 AnsiString 中编码为单个字节时,您可能最终(试图)写入比 AnsiString 转换产生的字节更多的字节。
- 小心使用 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;
我正在操作 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;
实施意见:
- 使用TPath.Combine组合目录和文件名
- 使用 TEncoding.ANSI.GetBytes 将 UNICODE 字符串转换为 ANSI。您在上面使用的版本有问题,因为与 UNICODE 字符串等效的 AnsiString 的长度可能与 UNICODE 字符串不同,f.ex。当您的国家字符在 UNICODE 中编码为一对,但在 AnsiString 中编码为单个字节时,您可能最终(试图)写入比 AnsiString 转换产生的字节更多的字节。
- 小心使用 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;