2017-01-18 74 views
1

我正在處理.NET Core中的上傳,它們以IFormFile傳遞。在我最終傳遞要保存的文件之前,我需要操作流來移除Exif數據。但是,我不知道如何處理這個問題。我正在嘗試下面的代碼,但它不起作用,因爲stream只能在using聲明中使用。在使用語句中操作流

什麼是正確的方式來做這樣的事情?

public async Task<IActionResult> UploadImage(IFormFile image) 
{ 
    using (var stream = new MemoryStream()) 
    { 
     // image is IFormFile 
     await image.CopyToAsync(stream); 

     // doesn't work, stream is readonly 
     stream = StripExif(stream); 

     // save stream 
    } 

    return Ok(); 
} 

public static Stream StripExif(Stream stream) 
{ 
    stream.Seek(0, SeekOrigin.Begin); 

    // remove Exif data 

    return stream; 
} 
+0

感謝錯字修復,史蒂夫。 :) – vaindil

回答

2

StripExif實際上不是創建一個新的Stream,相反,它的變異的Stream傳遞給它,所以它不應該在所有將返回一個Stream。當呼叫者然後修改呼叫以反映其變異的參數,而不是創建一個新的流,問題消失:

public async Task<IActionResult> UploadImage(IFormFile image) 
{ 
    using (var stream = new MemoryStream()) 
    { 
     // image is IFormFile 
     await image.CopyToAsync(stream); 

     StripExif(stream); 

     // save stream 
    } 

    return Ok(); 
} 

public static void StripExif(Stream stream) 
{ 
    stream.Seek(0, SeekOrigin.Begin); 

    // remove Exif data 
} 
+0

我試過了,但是當我這樣做時,流本身沒有被操縱。不知道這是Exif剝離本身的問題,還是如果該流沒有被改變,我將不得不惹惱它。 – vaindil

+1

@vaindil在你顯示的代碼中,同樣的流正在返回,所以沒有必要返回它。如果你真的創建了一個新的流,而不是簡單地改變提供的流,那麼這與你提供的例子不同。 – Servy

+0

我剛剛證實,傳入的流不會被您提供的代碼改變。圖像庫正在正確處理代碼。我不知道我是否正在處理主要功能中的不正確流,但未觸及。 – vaindil

1

使用只是有一個問題,因爲你試圖分配給使用變量。您可以在StripExif中創建新的MemoryStream,然後將StripExif的結果分配給新的流變量。

public async Task<IActionResult> UploadImage(IFormFile image) 
{ 
    using (var stream = new MemoryStream()) 
    { 
     // image is IFormFile 
     await image.CopyToAsync(stream); 

     var strippedStream = StripExif(stream); 

     // save strippedStream, not stream. 
    } 

    return Ok(); 
} 

public static MemoryStream StripExif(MemoryStream stream) 
{ 
    var result = new MemoryStream(); 

    stream.Seek(0, SeekOrigin.Begin); 

    // remove Exif data from result 

    return result; 
} 

更新時間:

public async Task<IActionResult> UploadImage(IFormFile image) 
{ 
    using (var stream = new MemoryStream()) 
    using (var writer = new StreamWriter(new MemoryStream()) 
    { 
     // image is IFormFile 
     await image.CopyToAsync(stream); 

     var strippedStream = StripExif(stream, writer); 

     // save strippedStream, not stream. 
    } 

    return Ok(); 
} 

public static void StripExif(MemoryStream stream, StreamWriter writer) 
{ 
    var result = new MemoryStream(); 

    // lets assume for sake of example that removing ExIf just removes the 
    // the first 10 characters of the stream 
    stream.Seek(10, SeekOrigin.Begin); 

    writer.Write(stream.ReadToEnd());   
} 
+0

這是否會破壞使用聲明的目的?如果我正在創建一個新的流,它仍然需要處理,不是嗎? – vaindil

+0

它並沒有達到目的,因爲在使用流之前需要從iFormFile中檢索流。是的,你是正確的,返回的流仍然需要處理,但它必須通過手動關閉流在UploadImage中處理。另一個選擇是創建一個StreamWriter,並將其傳遞給StripExif(我將添加一些代碼) –

+0

@vaindil - updated –