2017-01-10 3 views
0

私はそれがあると仮定します。TFileStreamはpascal IO Append(F)と同等ですか?

FS := TFileStream.Create(FileName, fmOpenReadWrite); 
FS.Seek(0, soFromEnd); 

は正しいことですか?開いているモードが正しいか、おそらくfmOpenWriteか、またはfmShareDenyNoneを追加する必要がありますか?

PS:Rewrite(F)のために、私は実際にそれはあなたが見ることができる

FStream := TFileStream.Create(Filename, fmOpenWrite); 
FStream.Seek(0, soEnd); 

だろうTHandleStream

procedure LOG(const FileName: string; S: string); 
const 
    FILE_APPEND_DATA = 4; 
    OPEN_ALWAYS = 4; 
var 
    Handle: THandle; 
    Stream: THandleStream; 
begin 
    Handle := CreateFile(PChar(FileName), 
    FILE_APPEND_DATA, // Append data to the end of file 
    0, nil, 
    OPEN_ALWAYS, // If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183). 
       // If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero. 
    FILE_ATTRIBUTE_NORMAL, 0); 

    if Handle <> INVALID_HANDLE_VALUE then 
    try 
    Stream := THandleStream.Create(Handle); 
    try 
     S := S + #13#10; 
     Stream.WriteBuffer(S[1], Length(S) * SizeOf(Char)); 
    finally 
     Stream.Free; 
    end; 
    finally 
    FileClose(Handle); 
    end 
    else 
    RaiseLastOSError; 
end; 
+2

でそれらのそれぞれの定義を見つけることができますあなたは読みたい、なぜ読み取り/書き込みを使用していませんか?かわいくするには、 'THandleStream'を使って' CreateFile'と 'FILE_APPEND_DATA'フラグのハンドルを渡して、いつも追加するようにしてください。 –

+1

あなた自身で 'CreateFile'を呼び出すと、' OPEN_ALWAYS'作成処理を使用できるようになり、ファイルが存在するかどうかについて競合条件が発生しないようにします。 –

答えて

4

を使用して終了デビッドのコメント@に基づいてFS := TFileStream.Create(FileName, fmCreate);


を使用TBinaryWriter.Createまたはの例- またはこれらのクラスの1つを直接使用することを選択するだけです。

+1

宣言されていない識別子: 'soEnd' – zig

+0

soFromEnd :) - http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_soFromEnd.html – RBA

+3

Delphiのバージョンによって異なります。ベルリンでは、私たちは 'TSeekOrigin =(soBeginning、soCurrent、soEnd); 'を持っています。あなたがバージョンを指定しなかったので、私は通常、現在のバージョンを想定しています。 –

1

また、そのファイルが作成されたファイルが存在しないかどうかを確認し、そうでない場合、この

var 
    FileName: string; 
    FS: TFileStream; 
    sOut: string; 
    i: Integer; 
    Flags: Word; 
begin 
    FileName := ...; // get your file name from somewhere 
    Flags := fmOpenReadWrite; 
    if not FileExists(FileName) then 
    Flags := Flags or fmCreate; 
    FS := TFileStream.Create(FileName, Flags); 
    try 
    FS.Position := FS.Size; // Will be 0 if file created, end of text if not 
    sOut := 'This is test line %d'#13#10; 
    for i := 1 to 10 do 
    begin 
     sOut := Format(sOut, [i]); 
     FS.Write(sOut[1], Length(sOut) * SizeOf(Char)); 
    end; 

    finally 
    FS.Free; 
    end; 
end; 

のように、このコードでなければなりません。フラグに関する

、あなたはdocumentation

+3

これは 'TFileStream'の大きな弱点です。 OPEN_ALWAYS作成処理へのアクセス権がありません。私のコードでは 'CreateFile'を呼び出してから' THandleStream'を使います。利便性以外にも、競合状態を避けることができます。 –

関連する問題