我試圖測量FILE_FLAG_WRITE_THROUGH
和FILE_FLAG_NO_BUFFERING
對文件中一系列寫入的影響,如another question中的請求。但是我發現我不能用FILE_FLAG_NO_BUFFERING
組寫一個文件。爲什麼使用FILE_FLAG_NO_BUFFERING打開文件時寫入失敗?
當我使用它時,德爾福返回EWriteError
與消息stream read error
。
使用的代碼如下:
procedure TForm1.btn1Click(Sender: TObject);
var
fsFSArquivoAAC: TFileStream;
L, lastErr: Cardinal;
R: WideString;
hn: THandle;
begin
hn := Windows.CreateFile(PChar('TesteAAC.AAC2'),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING, 0);
lastErr := GetLastError();
if (lastErr <> ERROR_SUCCESS) then
begin
if (lastErr <> ERROR_ALREADY_EXISTS) then
begin
MessageDlg('Whoops, something went wrong with CreateFile!',
mtError, [mbOK], 0);
end
else
begin
SetLastError(ERROR_SUCCESS);
end;
end;
fsFSArquivoAAC := TFileStream.Create(hn);
try
R := 'BatatinhaquandoNasceEspalharamapelochao';
// write WideString
L := Length(R);
fsFSArquivoAAC.WriteBuffer(L, SizeOf(integer));
if L > 0 then
fsFSArquivoAAC.WriteBuffer(R[1], L * SizeOf(WideChar));
finally
fsFSArquivoAAC.Free;
end;
如果你對此有何評論FILE_FLAG_NO_BUFFERING
代碼工作。爲什麼?
請注意,您沒有正確處理錯誤。你只是創建一個異常對象,然後丟棄它。你打算使用'raise',但更好的是,使用'RaiseLastOSError'來代替。但是由於在調用'CreateFile'和檢查失敗的時間之間可能會調用大量的OS函數,因此最好將文件句柄存儲在單獨的變量中,立即檢查*,然後*將它傳遞給構造函數。並記住'try'''finally',這樣你就可以釋放流並在異常情況下關閉文件句柄(比如'EWriteError')。 –
@RobKennedy感謝您的編輯。你是對的。該代碼根本沒有做異常處理。另外,我並不想將它複雜化,因爲簡單的代碼只是顯示錯誤。我希望現在好一點。還是想到了同樣的錯誤。 – EMBarbosa