Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用图像对象覆盖C#中上载的图像_C#_.net_Asp.net Mvc_Image_File Io - Fatal编程技术网

无法使用图像对象覆盖C#中上载的图像

无法使用图像对象覆盖C#中上载的图像,c#,.net,asp.net-mvc,image,file-io,C#,.net,Asp.net Mvc,Image,File Io,我正在尝试使用MVC框架在C#中创建一个实用程序,其中用户上载一张图片,用于从中裁剪出用作缩略图图标的片段(在任何给定时间,一次只有一个用户会这样做)。然后用户可以上传不同的图片并继续裁剪 我有一个控制器操作来处理文件上传,拍摄照片,将其从任何格式转换为jpeg,并将其保存为“temp.jpg”(我知道它不是瘦控制器,但这只是为了测试目的)。当他们上传下一张图片时,我想用这个新图片替换temp.jpg。该控制器在我的机器上的开发中工作良好,但在生产中,用户上载第一个图像并尝试用另一个图像替换后,

我正在尝试使用MVC框架在C#中创建一个实用程序,其中用户上载一张图片,用于从中裁剪出用作缩略图图标的片段(在任何给定时间,一次只有一个用户会这样做)。然后用户可以上传不同的图片并继续裁剪

我有一个控制器操作来处理文件上传,拍摄照片,将其从任何格式转换为jpeg,并将其保存为“temp.jpg”(我知道它不是瘦控制器,但这只是为了测试目的)。当他们上传下一张图片时,我想用这个新图片替换temp.jpg。该控制器在我的机器上的开发中工作良好,但在生产中,用户上载第一个图像并尝试用另一个图像替换后,会出现以下错误:

“该进程无法访问该文件,因为其他进程正在使用该文件”

在我看来,“temp.jpg”文件在第一次上传后被锁定,我不知道如何避免这种情况

欢迎提出任何建议或其他想法

分解我的代码的功能:

  • 检查是否要上载图片 存在于服务器上,并在找到时将其删除
  • 按原样保存图片 它是原始文件名和扩展名
  • 检查“temp.jpg”文件并在找到时将其删除
  • 打开System.Drawing.image对象中的原始图像以转换为jpeg
  • 将其另存为新的“temp.jpg”以替换删除的文件
我的代码:

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult PicUpload(DateTime sd, FormCollection collection)
    {
            foreach (string file in Request.Files)
            {
                HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
                    if (hpf.ContentLength == 0)
                        continue;
                    string savedFileName = Path.Combine(
                       AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\",
                       Path.GetFileName(hpf.FileName));

                    FileInfo temp = new FileInfo(savedFileName);
                    if (temp.Exists) temp.Delete();

                    hpf.SaveAs(savedFileName);

                    string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";

                    temp = new FileInfo(tempFileName);
                    if (temp.Exists) temp.Delete();

                    EncoderParameters codecParams = new EncoderParameters(1);
                    codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
                    ImageCodecInfo[] encoders;
                    encoders = ImageCodecInfo.GetImageEncoders();

                    Image newPic = Image.FromFile(savedFileName);
                    newPic.Save(tempFileName, encoders[1], codecParams);
                    newPic.Dispose();

                    FileInfo tmp = new FileInfo(savedFileName);
                    if (tmp.Exists) tmp.Delete();
                    return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
            }
            return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
    }

您可以为
tempFileName
使用一个唯一命名的临时文件,而不是“temp.jpg”。它有一个可用于此目的的方法

另一种选择是使用返回随机路径或文件名的方法(也在
System.IO.Path
中),然后只需对代码进行一点小的更改:

- string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";
+ string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\" + System.IO.Path.GetRandomFileName();

您可以为
tempFileName
使用一个唯一命名的临时文件,而不是“temp.jpg”。它有一个可用于此目的的方法

另一种选择是使用返回随机路径或文件名的方法(也在
System.IO.Path
中),然后只需对代码进行一点小的更改:

- string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";
+ string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\" + System.IO.Path.GetRandomFileName();
System.Drawing.Image.Save()无法保存到打开文件的位置:

From:“不允许将图像保存到构造图像的相同文件中,并引发异常。”

System.Drawing.image.Save()无法保存到打开文件的相同位置:


From:“不允许将图像保存到构造图像的文件中,并引发异常。”

结果是,在返回图像宽度和高度属性的代码的另一部分中,我没有正确释放图像的资源。也可以使用
Dispose()方法,我将代码放入“使用块”中,如下所示:

            using (Image newPic = Image.FromFile(savedFileName))
            {
                newPic.Save(tempFileName, encoders[1], codecParams);
            }

这就像一个符咒,我现在可以删除temp.jpg文件而不受惩罚。

事实证明,我没有在代码的另一部分中正确释放图像的资源,该部分返回图像的宽度和高度属性。也可以使用
Dispose()方法,我将代码放入“使用块”中,如下所示:

            using (Image newPic = Image.FromFile(savedFileName))
            {
                newPic.Save(tempFileName, encoders[1], codecParams);
            }

这就像一个符咒,我现在可以删除temp.jpg文件而不受惩罚。

使用“面板”控件,并将其保存为BMP,PNG,无论什么

使用“面板”控件,并将其保存为BMP,PNG,无论什么

我不会将其保存到同一位置。我编辑了我的问题,以使我的代码试图做的更清楚。简而言之,我保存该文件,然后尝试创建一个名为“temp.jpg”的副本,但如果该文件在上次上载时已被锁定,我无法将其删除以覆盖它。我不会将其保存到同一位置。我编辑了我的问题,以使我的代码试图做的更清楚。简而言之,我保存文件,然后尝试创建一个名为“temp.jpg”的副本,但如果该文件在上次上载时已被锁定,我无法将其删除以覆盖该文件。这可能会起作用,但我必须存储文件名并让视图引用该文件。这很可能是您最终必须执行的操作。不过,有一个问题,如果文件被锁定,即使我得到了一个随机文件名,在用户上传了一个新的随机文件名后,当我稍后尝试清理它时,该文件不会仍然被锁定吗?这可能有效,尽管我必须存储文件名并让我的视图引用它。这很可能是你最终必须做的事情。但有一个问题,如果文件被锁定,即使我得到一个随机文件名,在用户上载了一个新的随机文件名后,当我稍后尝试清理它时,该文件不会仍然被锁定吗?