【问题标题】:Leaving a BinaryReader object un-disposed in order to keep Request.InputStream alive?保留 BinaryReader 对象以保持 Request.InputStream 活着?
【发布时间】:2011-06-19 07:27:52
【问题描述】:

我有几种方法可以使用 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);
}

【问题讨论】:

    标签: c# asp.net inputstream


    【解决方案1】:

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

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

    【讨论】:

    • MiscUtil - NonClosingStreamWrapper 或类似中也有一个完全实现的装饰器。
    【解决方案2】:

    通过从另一个方法调用一个方法,您可以在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 扩展方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 2013-12-05
      相关资源
      最近更新 更多