为了使 Request.InputStream 保持活动状态而保留 BinaryReader 对象未释放?
我有几种方法可以使用 Request.InputStream 处理图像的保存。我有两个共享 HttpContext 的扩展。在我的一种方法中,我使用 BinaryReader 读取内容并进行处理。然而,自然地,在处置 BinaryReader 时,它会关闭 Request 上的 InputStream 属性。我的第二种方法使用相同的输入流来创建缩略图。
基本上,我需要一种方法在第一个方法中处理读取器后保持 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);
}
I have a couple methods to handle the saving of an image using Request.InputStream. I have two extensions that share the HttpContext. In one of my methods, I'm using a BinaryReader to read in the contents and do the processing. However, naturally, when disposing the BinaryReader, it closes off the InputStream property on Request. My SECOND method uses the same input stream to create a thumbnail.
Bascially, I need a way to keep the Request.InputStream property alive after disposing the reader in the first method. Is this possible? Here are my two methods. SaveImageStream() is called first, then 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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用“装饰器”模式来包装InputStream。查看本文末尾的示例:
http://ydie22.blogspot.com/2008/02/about-idisposable-close-streams-and.html
You could use the "decorator" pattern to wrap the InputStream. Have a look at the end of this post for an example:
http://ydie22.blogspot.com/2008/02/about-idisposable-close-streams-and.html
通过从一种方法调用另一种方法,您可以在
using
语句中执行所有操作。我还想知道这一行:您没有在任何地方使用
file
变量,该变量将整个请求流驻留在内存中。如果您不小心,这将成为拒绝服务攻击的途径。但是解决方案...将缩略图方法更改为如下所示:
或者,您可以在该
file
属性周围使用 MemoryStream,并将其发送到GenerateThumbnail
扩展方法。By calling one method from another, you can do everything within the
using
statement. I'm also wondering about this line:You aren't using the
file
variable anywhere, which has the entire request stream resident in memory. If you aren't careful this would be an avenue for a Denial of Service attack. But on to the solution...Change the thumbnail method to look like this:
Alternatively, you can use a MemoryStream around that
file
attribute, and send that to theGenerateThumbnail
extension method.