上传图像文件时,OutOfMemoryException C#
我一直在制作一幅英勇的形象。当用户上传图像时,我现在检查文件的大小。如果小于1MB,我会检查文件是否为图像类型。最后,我将图像调整到合适的大小,并创建图像的小缩略图。但是,自从添加代码来检查类型以来,我一直在体验OutOfMemoryException和OutOfMemoryException 以下是我的控制器方法:上传图像文件时,OutOfMemoryException C#,c#,asp.net-mvc,C#,Asp.net Mvc,我一直在制作一幅英勇的形象。当用户上传图像时,我现在检查文件的大小。如果小于1MB,我会检查文件是否为图像类型。最后,我将图像调整到合适的大小,并创建图像的小缩略图。但是,自从添加代码来检查类型以来,我一直在体验OutOfMemoryException和OutOfMemoryException 以下是我的控制器方法: [AcceptVerbs(HttpVerbs.Post)] public ActionResult Upload(Image image, HttpPost
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(Image image, HttpPostedFileBase ImageFile)
{
if (ImageFile.ContentLength > 0)
{
// Get the size in bytes of the file to upload.
int fileSize = ImageFile.ContentLength;
// Allow only files less than 1,048,576 bytes (approximately 1 MB) to be uploaded.
if (fileSize < 1048576)
{
string fileclass = "";
using (BinaryReader r = new BinaryReader(ImageFile.InputStream))
{
byte buffer = r.ReadByte();
fileclass = buffer.ToString();
buffer = r.ReadByte();
fileclass += buffer.ToString();
r.Close();
}
switch (fileclass)
{
case "7137":
case "255216":
case "13780":
try
{
string path = Server.MapPath("~/Uploads/");
ImageFile.SaveAs(path + ImageFile.FileName);
ResizeImageHelper resizeImageHelper = new ResizeImageHelper();
resizeImageHelper.ResizeImage(path + ImageFile.FileName, path + ImageFile.FileName, 640, 480, false);
resizeImageHelper.ResizeImage(path + ImageFile.FileName, path + "thumb" + ImageFile.FileName, 74, 74, false);
image.imageLocation = ImageFile.FileName;
image.imageThumb = "thumb" + ImageFile.FileName;
imageRepository.Add(image);
imageRepository.Save();
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
return View("Error");
}
}
}
else
{
//If file over 1MB
return View("Error");
}
}
else
{
//If file not uploaded
return View("Error");
}
return View("Error");
}
我假设这不会在第一次运行时发生,但是在一段时间之后。这是正确的吗
编辑:删除了不正确的假设,但IDisposable仍然存在问题
您没有处理NewImage,这将导致生产中出现问题 我通常会说“只是使用一个using”,但try/finally是一样的。根据您的判断,重构到我们这里来
System.Drawing.Image NewImage = null;
System.Drawing.Image FullsizeImage = null;
try
{
FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);
[... snip ... ]
NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);
// Clear handle to original file so that we can overwrite it if necessary
FullsizeImage.Dispose();
// Save resized picture
NewImage.Save(NewFile);
}
finally
{
if (FullsizeImage != null)
FullsizeImage.Dispose();
if (NewImage != null)
NewImage.Dispose();
}
好了,伙计们,在发现这部分代码后,问题出在:
using (BinaryReader r = new BinaryReader(ImageFile.InputStream))
{
byte buffer = r.ReadByte();
fileclass = buffer.ToString();
buffer = r.ReadByte();
fileclass += buffer.ToString();
r.Close();
}
我把它改成这样:
string fileclass = ImageFile.ContentType.ToString();
并将我的switch语句更改为:
switch (fileclass)
{
case "image/jpg":
case "image/jpeg":
case "image/png":
case "image/gif":
try
我还实施了罗伯特的建议。但是,作为.NET的新手,我不确定这种检查文件类型的方法是否与以前的方法一样准确?我的研究似乎表明,即使up loader更改了扩展名(例如,将example.exe重命名为example.jpg),previous也可以发现文件类型。我不确定使用提供的.NET功能是否仍然可以实现相同的功能 异常发生在哪里?我刚刚计算出它发生在这一行:System.Drawing.Image FullsizeImage=System.Drawing.Image.FromFile(原始文件);然而,在我开始把所有的检查放在适当的位置之前,这是有效的。在第一次运行时不会发生这种情况。查看此行ImageFile.SaveAs(path+ImageFile.FileName)上的逻辑;文件未正确保存在文件夹中。它显示为0字节。我明白了。您的图像大小调整代码仍然缺失,它是可识别的。请释放调用。对于任何IDisposable对象,您都应该养成使用该对象来处理.Dispose()调用的习惯。使用(Image newImage=FullSizeImage.GetThumbnailImage(newWidth,newHeight,null,IntPtr.Zero){//do stuff with newImage}//结束作用域自动处理object@Michael是的,这也是我写的,但别担心-所写的try/finally代码相当于编译器将使用using块生成的代码。请看,我一时记不起来了,但是请求的
ContentType
可以由执行上载的客户端设置,如果在这种情况下,被恶意客户端欺骗。文件扩展名也是如此。因此我可能不想完全信任他们。您还可以检查System.Drawing.Image
实例的属性RawFormat
的类型为System.Drawing.Imaging.ImageFormat
,并将其与静态实例进行比较。例如如果(UploadeImage.RawFormat==ImageFormat.Jpeg).
string fileclass = ImageFile.ContentType.ToString();
switch (fileclass)
{
case "image/jpg":
case "image/jpeg":
case "image/png":
case "image/gif":
try