TFileStream 的行为很奇怪
TFileStream behaves very strange
我有这个代码单元:(我在 Win XP sp 3 上 运行 Delphi 7)。
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
CONST
EOL = #13#10;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
Procedure StringToStream(Ofile : TFileStream; Const StrValue : String);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1 : TForm1;
Curdir : String;
Ofile : TFileStream;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Ofile := TFileStream.Create(curdir + '\TESTfil.HTML', fmCreate,fmsharedenynone);
try
StringToStream(Ofile, '<HTML><BODY> </BODY></HTML>' + EOL);
// StringToStream(Ofile, '</BODY></HTML>' + EOL);
finally
Ofile.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Curdir := ExtractFileDir(Application.ExeName);
end;
Procedure Tform1.StringToStream(Ofile : TFileStream; Const StrValue : String);
BEGIN
IF length(StrValue) > 0 then
Ofile.Write(StrValue,length(StrValue));
Ofile.Write('testpunkt',9);
END;
而这个单元的输出是:
"28 non printable characters" + "\testpunkt"
我试图将字符串设为 "CONST" 。 --> 同样的错误
我已经用 PCHAR 试过了——有很多错误……(主要是语法错误)
我已将 INDY7 更改为 INDY9 以获得 idGlobal.WriteStringtoStream() - 但特定的 INDY-9 不支持 WriteStringToStream 。
我做错了什么?
您写的是字符串的地址,而不是它的内容。要将字符串写入流,请使用以下代码:
procedure TForm1.StringToStream(Ofile: TFileStream; const StrValue: string);
begin
Ofile.WriteBuffer(Pointer(StrValue)^, Length(StrValue));
end;
这里我取消了指针的引用,所以写入了字符串的内容。
备注:
- 此代码不需要检查字符串是否为空。
- 既然你用的是Delphi7,字符串是ANSI,那么传
Length(StrValue)
也是合理的。如果您曾经转向 Unicode,那么您将不得不修改代码以解决编码问题。
- 我使用
WriteBuffer
而不是 Write
因为前者会在出错的情况下引发异常,与 Write
. 相反
- 您的代码假定写入与可执行文件相同的目录是安全的。如果您部署程序,该假设可能会被打破。
- 你对全局变量的使用只会让你跌倒。请参阅尽可能使用局部变量,作为参数传递的变量,类 的数据成员。顺全局。
- 写作 XML 充满了复杂性。尝试使用原始字符串操作这样做可能会在未来的某个时候导致许多编码问题。明智的做法是现在使用 XML 库,这样您以后就不必重新编写代码了。
我有这个代码单元:(我在 Win XP sp 3 上 运行 Delphi 7)。
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
CONST
EOL = #13#10;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
Procedure StringToStream(Ofile : TFileStream; Const StrValue : String);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1 : TForm1;
Curdir : String;
Ofile : TFileStream;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Ofile := TFileStream.Create(curdir + '\TESTfil.HTML', fmCreate,fmsharedenynone);
try
StringToStream(Ofile, '<HTML><BODY> </BODY></HTML>' + EOL);
// StringToStream(Ofile, '</BODY></HTML>' + EOL);
finally
Ofile.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Curdir := ExtractFileDir(Application.ExeName);
end;
Procedure Tform1.StringToStream(Ofile : TFileStream; Const StrValue : String);
BEGIN
IF length(StrValue) > 0 then
Ofile.Write(StrValue,length(StrValue));
Ofile.Write('testpunkt',9);
END;
而这个单元的输出是:
"28 non printable characters" + "\testpunkt"
我试图将字符串设为 "CONST" 。 --> 同样的错误
我已经用 PCHAR 试过了——有很多错误……(主要是语法错误)
我已将 INDY7 更改为 INDY9 以获得 idGlobal.WriteStringtoStream() - 但特定的 INDY-9 不支持 WriteStringToStream 。
我做错了什么?
您写的是字符串的地址,而不是它的内容。要将字符串写入流,请使用以下代码:
procedure TForm1.StringToStream(Ofile: TFileStream; const StrValue: string);
begin
Ofile.WriteBuffer(Pointer(StrValue)^, Length(StrValue));
end;
这里我取消了指针的引用,所以写入了字符串的内容。
备注:
- 此代码不需要检查字符串是否为空。
- 既然你用的是Delphi7,字符串是ANSI,那么传
Length(StrValue)
也是合理的。如果您曾经转向 Unicode,那么您将不得不修改代码以解决编码问题。 - 我使用
WriteBuffer
而不是Write
因为前者会在出错的情况下引发异常,与Write
. 相反
- 您的代码假定写入与可执行文件相同的目录是安全的。如果您部署程序,该假设可能会被打破。
- 你对全局变量的使用只会让你跌倒。请参阅尽可能使用局部变量,作为参数传递的变量,类 的数据成员。顺全局。
- 写作 XML 充满了复杂性。尝试使用原始字符串操作这样做可能会在未来的某个时候导致许多编码问题。明智的做法是现在使用 XML 库,这样您以后就不必重新编写代码了。