在using语句中操作流

时间:2017-01-18 19:14:58

标签: c# stream asp.net-core .net-core

我正在处理.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;
}

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:1)

由于您尝试分配使用变量,因此使用只会出现问题。您可以在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());        
}