是否取消处理BinaryReader对象以使Request.InputStream保持活动状态?

时间:2011-02-01 14:09:40

标签: c# asp.net inputstream

我有两种方法可以使用Request.InputStream来处理图像的保存。我有两个共享HttpContext的扩展。在我的一个方法中,我使用BinaryReader读取内容并进行处理。但是,当然,在处理BinaryReader时,它会关闭Request上的InputStream属性。我的SECOND方法使用相同的输入流来创建缩略图。

基本上,我需要一种方法来在第一种方法中处理读取器后保持Request.InputStream属性。这可能吗?这是我的两种方法。首先调用SaveImageStream(),然后调用GenerateThumbnail()。

public static void SaveImageStream(this HttpContextBase ctx, string filename)
{
    var config = ObjectFactory.GetInstance<IConfig>();

    using (var reader = new BinaryReader(ctx.Request.InputStream))
    {
        var bandImagesPath = config.GetSetting<string>("BandImagePath");
        var path = Path.Combine(ctx.Server.MapPath(bandImagesPath), filename);

        byte[] file = reader.ReadBytes((int)ctx.Request.InputStream.Length);

        using (var outputStream = System.IO.File.Create(path, 2048))
        {
            const int chunkSize = 2 * 1024; // 2KB
            byte[] buffer = new byte[chunkSize];
            int bytesRead;
            ctx.Request.InputStream.Position = 0;
            while ((bytesRead = ctx.Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                outputStream.Write(buffer, 0, bytesRead);
            }
        }
    }
}

public static void GenerateThumbnail(this HttpContextBase ctx, string filename)
{
    var config = ObjectFactory.GetInstance<IConfig>();

    int size = config.GetSetting<int>("ThumbSize");
    var thumbPath = Path.Combine(ctx.Server.MapPath(config.GetSetting<string>("ThumbPath")), filename);

    var image = System.Drawing.Image.FromStream(ctx.Request.InputStream);
    var thumb = image.GetThumbnailImage(size, size, null, IntPtr.Zero);

    thumb.Save(thumbPath, System.Drawing.Imaging.ImageFormat.Png);
}

2 个答案:

答案 0 :(得分:2)

您可以使用“装饰器”模式来包装InputStream。看看这篇文章的结尾是一个例子:

http://ydie22.blogspot.com/2008/02/about-idisposable-close-streams-and.html

答案 1 :(得分:0)

通过从另一个方法调用一个方法,您可以在using语句中执行所有操作。我也想知道这一行:

byte[] file = reader.ReadBytes((int)ctx.Request.InputStream.Length);

您没有在任何地方使用file变量,它将整个请求流驻留在内存中。如果您不小心这将是拒绝服务攻击的途径。但是对于解决方案......

将缩略图方法更改为如下所示:

public static void SaveImageStream(this HttpContextBase ctx, string filename)
{
    var config = ObjectFactory.GetInstance<IConfig>();

    using (var reader = new BinaryReader(ctx.Request.InputStream))
    {
        var bandImagesPath = config.GetSetting<string>("BandImagePath");
        var path = Path.Combine(ctx.Server.MapPath(bandImagesPath), filename);

        using (var outputStream = System.IO.File.Create(path, 2048))
        {
            const int chunkSize = 2 * 1024; // 2KB
            byte[] buffer = new byte[chunkSize];
            int bytesRead;
            ctx.Request.InputStream.Position = 0;
            while ((bytesRead = ctx.Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                outputStream.Write(buffer, 0, bytesRead);
            }
        }

        ctx.Request.InputStream.Position = 0;
        ctx.GenerateThumbnail(filename);
    }
}

或者,您可以在file属性周围使用MemoryStream,并将其发送到GenerateThumbnail扩展方法。