2010-07-22 4 views
0

바이너리 기록기를 사용하여 몇 uint와 바이트 배열로 구성된 레코드를 파일에 쓰는 방법이 있습니다. 이 방법은 내 프로그램의 일부로 초당 약 12 ​​번 실행됩니다.binarywriter가 스트림 끝 부분에 파일을 열지 않음

iLogFileMutex.WaitOne(); 
using (BinaryWriter iBinaryWriter = new BinaryWriter(File.Open(iMainLogFilename, FileMode.OpenOrCreate, FileAccess.Write))) 
{ 
    iBinaryWriter.Seek(0, SeekOrigin.End); 
    foreach (ViewerRecord vR in aViewerRecords) 
    { 
     iBinaryWriter.Write(vR.Id); 
     iBinaryWriter.Write(vR.Timestamp); 
     iBinaryWriter.Write(vR.PayloadLength); 
     iBinaryWriter.Write(vR.Payload);   
    } 
}  
iLogFileMutex.ReleaseMutex(); 

위의 코드는 잘 작동하지만 내가 추구 호출로 라인을 제거하면, 결과 이진 파일이 손상되었습니다 : 코드는 다음과 같습니다. 예를 들어 대다수의 레코드가 잘 작성되었지만 일부 레코드가 완전히 없거나 일부만 존재합니다. 따라서 버그의 원인은 파일을 반복해서 열고 닫을 때 파일의 현재 위치가 항상 끝이 아니라 모든 것이 덮어 쓰기된다는 것입니다.

내 질문은 : 왜 파일을 열 때 C#이 현재 위치가 끝났음을 보장하지 않습니까?

PS : 나는 당신이 파일에 추가 할 경우이 버그

답변

1

이 문제는 FileMode.OpenOrCreate와 ViewerRecord 멤버 유형의 조합입니다. 그 중 하나 이상은 고정 된 크기 유형이 아니며 아마도 문자열입니다.

파일이 이미 존재하면 문제가 발생합니다. 기존 데이터를 덮어 쓰면서 파일의 시작 부분에 데이터 쓰기를 시작합니다. 그러나 작성한 내용은 우연히 기존 레코드를 덮어 쓰게됩니다. 문자열은 똑같은 크기 여야합니다. 충분한 레코드를 작성하지 않으면 이전 레코드를 모두 덮어 쓰지 않습니다. 파일을 읽을 때 문제가 생기면 마지막으로 기록한 레코드를 읽은 후에 이전 레코드의 일부분을 읽습니다. 당신은 잠시 쓰레기가 될 것입니다.

레코드를 고정 크기로 설정해도 문제가 해결되지 않으면 좋은 레코드를 읽지 만 이전 레코드는 읽게됩니다. 어떤 오래된 레코드를 얻을지는 당신이 쓴 새로운 데이터의 양에 달려 있습니다. 이는 왜곡 된 데이터를 읽는 것만 큼 나 빠지게됩니다.

이전 레코드를 보존해야하는 경우 FileMode.Append 파일에 추가해야합니다. 그렇지 않으면 FileMode.Create 파일을 다시 작성해야합니다.

+0

그걸 설명해, 건배 :) – CalumMcCall

4

을 일으키는 스레딩 문제를 배제했다, 그렇지 않으면 파일에 설정된 위치에 열립니다, 당신의 열기 통화를 FileMode.APPEND을 사용해야합니다 파일의 시작이 아니라 끝.

+0

매우 사실, 나는 내 게시물에서 그것을 지적해야합니다. 그러나, 나는 여전히 문제없이 작성된 첫 번째 파일을 포함하여 많은 양의 레코드를 얻는 반면, 파일의 절반 정도는 기록을 작성하고 절반은 기록한 다음 그 후에도 괜찮습니다. 그것을 추가하거나 부족하면 그렇게하지 않을 것입니까? 필자는 파일에 실제로 기록 된 레코드의 마지막 목록 만 가져야합니까? – CalumMcCall

+0

그래서 문제가있는 코드가 실제로 게시 된 코드가 아닙니다. –

관련 문제