2012-05-30 2 views
2

나는 another question의 요청으로 파일의 쓰기 순서에 FILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERING의 효과를 측정하려고합니다. 하지만 나는 FILE_FLAG_NO_BUFFERING 파일을 쓸 수 없다는 것을 발견했습니다.FILE_FLAG_NO_BUFFERING을 사용하여 파일을 열 때 파일 쓰기가 실패하는 이유는 무엇입니까?

델파이를 사용하면 EWriteErrorstream 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을 언급합니다. 왜?

+1

오류를 올바르게 처리하지 않는다는 점에 유의하십시오. 방금 예외 객체를 생성 한 다음이를 버리는 것입니다. 당신은'raise'를 사용하려고했으나 더 나은 방법은'RaiseLastOSError'를 사용하는 것입니다. 그러나'CreateFile'을 호출하는 시간과 실패를 확인하는 시간 사이에 많은 OS 함수가 호출 될 수 있기 때문에 별도의 변수에 파일 핸들을 저장하고 * 즉시 * 확인한 다음 * 다음에 전달하는 것이 좋습니다 생성자. 'try'-'finally'를 기억해 두어 스트림을 해제하고 예외 ('EWriteError'와 같은)가 발생할 경우 파일 핸들을 닫습니다. –

+0

@RobKennedy 편집 해 주셔서 감사합니다. 당신 말이 맞아요. 코드는 예외 처리를 전혀하지 않았습니다. 또한 간단한 코드가 오류를 보여주기 때문에 복잡하게 만들고 싶지는 않습니다. 나는 그것이 지금 더 나아지기를 바랍니다. 여전히 같은 오류가 생각됩니다. – EMBarbosa

답변

7

당신이 사용하는 경우 FILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERING는 메모리에 버퍼를 정렬 디스크 섹터와 쓰기를 정렬 및 섹터 크기의 배수로 (내가 생각하는) 쓰기 various requirements있다. 당신은 이런 일들을하는 것처럼 보이지 않습니다.

+0

아마도 맞을 것입니다. 어쩌면 내가 그 오류가 "스트림 ** 읽기 ** 오류"라고 의아해했다. 나는 그것을 확인하려고 노력하고있다. – EMBarbosa

+0

동일한 동작이지만 다른 오류를 나타내는 [Old New Thing의 관련 게시물] (http://blogs.msdn.com/b/oldnewthing/archive/2010/04/14/9995509.aspx) – EMBarbosa

관련 문제