나는 another question의 요청으로 파일의 쓰기 순서에 FILE_FLAG_WRITE_THROUGH
및 FILE_FLAG_NO_BUFFERING
의 효과를 측정하려고합니다. 하지만 나는 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