2017-01-18 11 views
1

Я обрабатываю загрузки в .NET Core, которые передаются как IFormFile. Мне нужно манипулировать потоком, чтобы удалить данные Exif, прежде чем я в конечном счете передам файл для сохранения. Однако я не знаю, как справиться с этим. Я пытаюсь использовать код ниже, но он не работает, потому что stream находится только в операторе using.Управление потоком внутри оператора 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

Использование имеет только проблему, поскольку вы пытаетесь присвоить переменную using. Вы можете создать новый MemoryStream в StripExif, а затем присвоить результат 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 - обновлено –

 Смежные вопросы

  • Нет связанных вопросов^_^