2012-11-10 3 views
3

에 StreamWriting 후 즉시 파일을 StreamReading :이 예제 코드를 감안할 때이 같은 파일

1: using (StreamWriter sw = new StreamWriter(@"C:\file.txt")) 
2: { 
3:  sw.WriteLine(great_string); 
4: } 
5: 
6: using (StreamReader sr = new StreamReader(@"C:\file.txt")) 
7: { 
8:  sr.ReadToEnd(); 
9: } 

StreamReader.ReadToEnd이 라인 (8)에 호출 될 때 3 행에 기록 된 great_stringC:\file.txt에 존재하지 않을 것이라고 할 수 있습니까? 평균적인 CPU가 평균 HDD보다 훨씬 빠르게 작동하기 때문에 가능할 것 같습니다. 그러나 지금까지 테스트 해봤습니다. 그리고 지금까지 3 행에 기록 된 문자열은 온라인 파일을 읽을 때 항상 나타납니다. 8. using 문이 모든 데이터가 파일에 쓰여지거나 파일에서 읽혀질 때까지 스트림을 닫지 않을 것이라고 생각하고 있으므로 내가 묻는 상황을 막을 수 있습니다.

내가 MSDN에 StreamWriter.Close 방법에 대해 읽어 봤는데, 그것은 다음과 같은 상태 :

당신은 모든 데이터가 올바르게 기본이되는 스트림에 기록되어 있는지 확인하려면 닫기를 호출해야합니다.

그러나 WHEN을 사용하면 데이터가 기본 스트림에 기록됩니다.

이 주제에 대한 정보를 미리 감사드립니다. 나는이 질문에 대한 해답을 찾았지만 아무 것도 찾지 못했다 ... 나는 무엇을 찾아야하는지 정말로 모른다.

답변

3

닫기를 호출 한 후 데이터가 물리적으로 HDD에 존재하지 않을 수 있지만 시스템 (Windows 커널)은 외관을 제공합니다. 중요한 것은 외관뿐입니다.

방금 ​​작성한 파일을 읽으면 Windows에서 HDD를 요청하거나 캐시에서 제공합니다.

이 경우가 아니라면 신뢰할 수있는 프로그램을 작성하기가 어려울 수 있습니다. 효과 순서가 함수와 프로세스 사이에서 임의로 변경 될 수 있기 때문입니다. 그것은 혼란이 될 것입니다. 따라서 시스템은 순차적 인 일관성을 보장합니다.

생각해 보면 :이 직렬화 속성이 없으면 파일에 여러 내용이 동시에있을 수 있습니다! 처음 읽으면 오래된 내용을 볼 수 있습니다. 다시 읽으면 갑자기 변경 사항이 표시됩니다. 다행히 이런 종류의 행동은 불가능합니다.

+1

"이것이 사실이 아니라면, 효과의 순서가 기능과 프로세스 사이에서 임의로 변경 될 수 있기 때문에 신뢰할 수있는 프로그램을 작성하기가 어려울 것입니다. 따라서 시스템은 일관성을 보장합니다." --- 나는 내 마음의 뒤쪽에서 비슷한 것을 생각하고 있었지만 그것을 어떻게 표현해야할지 몰랐다. 고마워, 이것은 매우 도움이된다. –

-1

대신 Flush을 사용해야합니다. 그러면 데이터를 쓸 수 있습니다. 나는 어쩌면 using 문은 모든 데이터 때까지 스트림 을 닫을 것이라고 생각하고

+1

아니요! 플러시는이 용도로 사용되지 않습니다. 닫기는 완전히 100 %의 경우에 충분합니다. 플러시 (Flush)는 캐시를 플러시 (flush)시키고 디스크 탐색을 유발합니다. – usr

+1

@usr : 제트기를 거기에서 식히십시오. 'Dispose'는 마음에 드는지 여부에 상관없이'Flush'를 호출합니다 (그리고'Close'는 단순히'Dispose (true)'를 호출합니다). –

+1

Dispose는 Flush를 호출하지 않습니다. 반사 된 코드를 잘못 읽고 있습니다. FileStream 내부 버퍼를 비우는 FlushWrite를 호출합니다. OS가 물리적으로 플러시하고 디스크 "fsync"를 발생 시키도록 권장하지는 않습니다. meta-point : Flush 호출은 일반적으로 좋지 않은 조언이며, 가능한 한 언제든지 조치를 취합니다. 일부 사람들은 Close, Flush, Dispose를 호출하고 using 블록을 닫을 것을 권장합니다. 그것은 미친 짓이야. – usr

2

따라서 내가 대해 부탁 해요 상황의 종류를 방지에/파일에서 읽어 기록됩니다.

예, 정확하게. using()은 객체가 완전히 삭제되었는지 확인합니다. using 문에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx?ppud=4을 참조하십시오.

즉, 파일을 닫기 전에 데이터가 플러시됩니다. 실제로 파일이 쓰여질 때까지 기다릴 것입니다.

+0

감사! 좋은 정보. –

1

alleywayjack 님의 답변이 맞습니다.타이밍을보기 :

static void Main() 
    { 
     var file = @"c:\temp\test.bin"; 
     String huge = new String(new char[20 * 1024 * 1024]); 
     var sw = new Stopwatch(); 
     var sw2 = new Stopwatch(); 
     sw.Start(); 
     using (var stream = new StreamWriter(file)) 
     { 
      sw2.Start(); 
      stream.Write(huge); 
      sw2.Stop(); 
     } 
     sw.Stop(); 
     sw2.Stop(); 

     Console.WriteLine("Write 20MB to cache: " + (sw.Elapsed.TotalMilliseconds - sw2.Elapsed.TotalMilliseconds)); 
     Console.WriteLine("Write 20MB from cache to HD: " + sw2.Elapsed.TotalMilliseconds); 
    } 

출력 : 전체 절차는 (동기)를 차단

Write 20MB to cache: 5 // ms (including preparing the stream) 
Write 20MB from cache to HD: 186 // ms 

.

+0

이 편지를 보내 주셔서 감사합니다. 방금이 코드를 실행했는데 차이점 (출력 결과에서 보았 듯이)은 매우 크지 만 놀라운 것은 아닙니다. 차이가 얼마나 큰지 알 수있는 것은 멋지다. –

관련 문제