2016-12-19 11 views
2

私はこのコードユニットを持っています:(私はWin XP sp 3上でDelphi 7を実行します)。TFileStreamは非常に奇妙な動作をします

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のでそれを試してみました

同じエラーが - 私はidGlobal.WriteStringtoStream()を取得するためにINDY9にINDY7を変更しているエラーの多く...(ほとんどの構文エラー)

を得た - しかし、それを特にINDY-9はWriteStringToStreamをサポートしていません。

私は間違っていますか?

+0

無関係な注記では、ユニットではなく、フォームクラス内で 'Curdir'と' Ofile'を真剣に宣言する必要があります。 'StringToStream'は' private'の上で宣言されるべきではなく 'プライベート」または「パブリック」のいずれかを選択します。 'private'の上のスペースは、通常、IDEによって制御されます。 –

+0

@ジェリードッジ:あなたは大丈夫です。このユニットは非常に時期尚早の例に過ぎませんでした。そして、私はそれを実行させなかったので、私はコードを短縮するためのいくつかのショートカットを行いました。私はあなたが提案した通りに私が行う本当のコードです。アドバイスをいただきありがとうございます。 –

答えて

5

あなたはその内容ではなく文字列のアドレスを書いています。ここで

procedure TForm1.StringToStream(Ofile: TFileStream; const StrValue: string); 
begin 
    Ofile.WriteBuffer(Pointer(StrValue)^, Length(StrValue)); 
end; 

私はポインタを間接参照し、その文字列の内容を書かれている:ストリームの使用にこのコードを文字列を書き込みます。

注:このコードは、空の文字列であることをチェックする必要はありません

  • Delphi 7を使用し、文字列がANSIであるため、Length(StrValue)を渡すのが妥当です。 Unicodeに移行した場合は、コードを修正してエンコーディングに対応する必要があります。
  • Writeとは対照的に、エラーの場合は前者が例外を発生させるため、WriteではなくWriteBufferを使用します。
  • コードでは、実行可能ファイルと同じディレクトリに書き込むことが安全であると想定しています。この仮定は、プログラムを配備した場合には崩壊する可能性があります。
  • グローバル変数を使用すると、秋に設定するだけです。可能であればローカル変数を使用し、変数はパラメータとして渡し、クラスのデータメンバーを使用することを参照してください。グローバルを黙らせる。
  • XMLを書くことは複雑です。未処理の文字列操作を使用してこれを行うと、将来のある時点でエンコードに多くの問題が発生する可能性があります。現在、XMLライブラリを使用することで、将来コードを書き直す必要はありません。
+0

Hefferman:すべてのアドバイスをいただきありがとうございます。私のメモ(Jerry Dodgeへのメモ)に書いたように、これは非常に簡単な例でした。あなたのアドバイスをありがとう。 –

関連する問題