2015-02-04 6 views
0

사진을 찍어 저장 버튼을 눌러 이미지를 컴퓨터에 저장하는 응용 프로그램이 있습니다. 이것은 대부분의 시간을 잘 작동합니다. 하지만 일부 사용자가 부패한 이미지를보고 있습니다. 이 이미지는 크기가 올바른 바이트 수에 대한 것이지만 이미지의 바이트 수를 시도하면 null 값이로드됩니다. 사진을 저장하는FileStream을 사용하여 이미지를 저장하면 파일이 손상 될 수 있습니다.

내 코드는 다음과 같습니다 FileStream Constructor (SafeFileHandle, FileAccess)에서

try 
{ 
    using (FileStream stream = new FileStream(localCopyFileLocation, FileMode.Create)) 
    { 
     JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.QualityLevel = quality; 
     encoder.Frames.Add(BitmapFrame.Create(photo, null, metadata, null)); 
     encoder.Save(stream); 
    } 
} 
catch (Exception ex) 
{ 
    //Write to log etc. 
} 

내가이 글을 읽을 닫기가 호출 될 때

가, 핸들도 닫히고 파일의 핸들 카운트가 감소합니다.

FileStream은 핸들 위에 단독 제어 이 있다고 가정합니다. FileStream이 인 동안 읽기, 쓰기 또는 검색을 수행하면 핸들이 손상되어 데이터가 손상 될 수 있습니다. 안전을 위해 핸들을 사용하기 전에 Flush를 호출하고 핸들 사용을 완료 한 후에는 Close가 아닌 메서드를 호출하지 마십시오.

그러나 이것이 무슨 뜻인지 확실하지 않습니다. 내 사용자가 파일을 쓰는 동안 태블릿을 잠자기 상태로 둘 수 있습니까? 이것이 일어나는 다른 이유는 무엇일까요?

+2

'save()'를 호출 한 후에'stream.Flush();'를 호출해야하는 것 같습니다. – kindasimple

+1

왜 'steam.Flush()'를 호출해야합니까? 그 부름은 무엇을 하는가? – user1

+0

올바른 생성자 문서가 있습니까? 이 [FileStream 생성자] (https://msdn.microsoft.com/en-us/library/47ek66wy(v=vs.110).aspx) –

답변

1

명확히하려면 Flush()으로 전화해야합니다.

Close()으로 전화하는 것만으로는 충분하지 않습니다. 반면에 다음과 같은

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if (this._handle != null && !this._handle.IsClosed && this._writePos > 0) 
     { 
      this.FlushWrite(!disposing); 
     } 
    } 
    finally 
    { 
     if (this._handle != null && !this._handle.IsClosed) 
     { 
      this._handle.Dispose(); 
     } 
     this._canRead = false; 
     this._canWrite = false; 
     this._canSeek = false; 
     base.Dispose(disposing); 
    } 
} 

을 수행 Close() 호출 Dispose(), 여기 Flush()는 무엇을 :

public override void Flush() 
{ 
    this.Flush(false); 
} 

호출하는 :

public virtual void Flush(bool flushToDisk) 
{ 
    if (this._handle.IsClosed) 
    { 
     __Error.FileNotOpen(); 
    } 
    this.FlushInternalBuffer(); 
    if (flushToDisk && this.CanWrite) 
    { 
     this.FlushOSBuffer(); 
    } 
} 

열쇠 (나는 생각하지만 확실하지 않습니다)은 FlushOSBuffer()

입니다.

Flush()을 호출 할 수없는 경우 Flush(true) 오버라이드를 시도하면 Win32 API FlushFileBuffers이 호출되어 중간 파일 버퍼가 플러시됩니다.

+0

당신이 말하는 것에서. 나는'Flush (true)'를 호출해야합니까? – user1

+0

네, 그럴 수는 없습니다. 어떻게되는지보십시오. 어느 쪽이든, 당신은 파일 버퍼가 비어 있음을 보장하기 위해'Flush()'메소드 중 하나를 호출 할 필요가있다. –

+0

무작위로 발생하는 것처럼 테스트하기가 어렵 기 때문에이 문제가 해결되었는지 확실하지 않습니다. 그러나이 대답은 내가 읽은 것으로부터 가장 이해가됩니다. – user1