【问题标题】:Web Application not able to Delete files for Read/Write Enabled Folders in ASP.NETWeb 应用程序无法删除 ASP.NET 中已启用读/写的文件夹的文件
【发布时间】:2012-09-01 08:27:02
【问题描述】:

当我试图删除我通过名为“SampleApplication”的网站上传的图像时,我可以看到堆栈跟踪中显示以下错误

 The process cannot access the file 'D:\Hosting\123456\html\App_Images\myfolder1\eKuK2511.png' because it is being used by another process.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.IOException: The process cannot access the file 'D:\Hosting\123456\html\App_Images\myfolder1\eKuK2511.png' because it is being used by another process.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[IOException: The process cannot access the file 'D:\Hosting\123456\html\App_Images\myfolder1\eKuK2511.png' because it is being used by another process.]
   System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +9723350
   System.IO.File.Delete(String path) +9545728
   SampleApplication.BasePage.DeleteApp_ImagesById(DataTable dt) +503
   SampleApplication.PostLease.MyAccount.DeleteAd_Property(Object sender, EventArgs e) +193
   System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +113
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +9
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +176
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272 

文件夹 App_Images 已被授予读/写权限并继承到子文件夹,即 myfolder1、myfolder2、myfolder3、myfolder4。即使我试图从 FTP 文件管理器中强制删除图像 eKuK2511.png,它仍显示以下错误:

550 The process cannot access the file because it is being used by another process. 

如何消除这个错误?

编辑: 上传代码:

public void UploadImages()
        {
            if (ServerSideValidation() == true)
            {
                string SavePath;
                ImgPaths = new List<string>();
                // Get the HttpFileCollection
                HttpFileCollection hfc = Request.Files;
                if (hfc.Count > 0)
                {
                    for (int i = 0; i < hfc.Count; i++)
                    {
                        HttpPostedFile hpf = hfc[i];
                        if (hpf.ContentLength > 0)
                        {
                            #region trials compression.
                            SavePath = "~/App_Images/" + Session["AppContext"].ToString() + "/" + GetUniqueKey() + GetFileExtension(hpf.FileName);
                            SaveImageByCompressing(hpf, SavePath);

                            #endregion
                            //SavePath can be saved in DB.
                            ImgPaths.Add(SavePath);
                            //Save Thumbnail Image.
                            if (i == 0)
                            {
                                string savedName = "Thumb_" + GetUniqueKey() + GetFileExtension(AppDomain.CurrentDomain.BaseDirectory + ImgPaths[0].ToString().Replace("~/", "\\").Replace("/", "\\"));
                                SavePath = "~/App_Images/" + Session["AppContext"].ToString() + "/" + savedName;
                                SaveThumbImage(AppDomain.CurrentDomain.BaseDirectory + ImgPaths[0].ToString().Replace("~/", "").Replace("/", "\\"), AppDomain.CurrentDomain.BaseDirectory + "App_Images\\" + Session["AppContext"].ToString() + "\\" + savedName, 75, 75);
                                ImgPaths.Add(SavePath);
                            }
                        }
                    }
                    Session.Remove("AppContext");
                    lblMsg.Text = "Images Uploaded Successfully.";
                    //ShowUploadedImages(ImgPaths);
                }
                else
                {
                    lblMsg.Text = "Images uploaded are either in wrong format or were deleted after uploading.";
                }
            }
            else
            {
                lstPaths = new List<string>();
                lblMsg.Text = "No Images Uploaded";
            }
        }

        private void SaveImageByCompressing(HttpPostedFile hpf, string filePath)
        {
            Image imgFromClient = Image.FromStream(hpf.InputStream);
            string SavetoFullPath = AppDomain.CurrentDomain.BaseDirectory + filePath.Replace("~/", "").Replace("/", "\\");
            Image.GetThumbnailImageAbort myCallbackCompressed = new Image.GetThumbnailImageAbort(ThumbnailCallback);
            Image imageToSave= imgFromClient.GetThumbnailImage(imgFromClient.Width, imgFromClient.Height, myCallbackCompressed, IntPtr.Zero);
            imageToSave.Save(SavetoFullPath, System.Drawing.Imaging.ImageFormat.Jpeg);

        }
        public static void SaveThumbImage(string imagePath, string filePath, int width = 0, int height = 0)
        {
            Image originalImage = Image.FromFile(imagePath);
            if (width > 0 && height > 0)
            {
                Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                Image imageToSave = originalImage.GetThumbnailImage(width, height, myCallback, IntPtr.Zero);
                imageToSave.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            else
            {
                originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }
        private static bool ThumbnailCallback() { return false; }

        private bool ServerSideValidation()
        {
            string errorMsg = string.Empty, temp = null;
            bool errorFlag = true;

            // Get the HttpFileCollection
            HttpFileCollection hfc = Request.Files;
            for (int i = 0; i < hfc.Count; i++)
            {
                HttpPostedFile hpf = hfc[i];
                if (hpf.ContentLength > 0 && hpf.FileName!=String.Empty)
                {
                    temp = ValidateImage(hpf);
                    if (temp != null)
                    {
                        errorMsg += GetFileName(hpf.FileName.ToString()) + " has error : " + temp;
                        temp = null;
                    }
                }
                else
                {
                    return false;
                }
            }

            if (!string.IsNullOrWhiteSpace(errorMsg))
            {
                lblMsg.Text = errorMsg;
                errorFlag = false;
            }
            return errorFlag;
        }

        private string GetFileExtension(string filePath)
        {
            FileInfo fi = new FileInfo(filePath);
            return fi.Extension;
        }

        private string GetFileName(string filePath)
        {
            FileInfo fi = new FileInfo(filePath);
            return fi.Name;
        }

        private string GetUniqueKey()
        {
            int maxSize = 8;
            char[] chars = new char[62];
            string a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

            chars = a.ToCharArray();

            int size = maxSize;
            byte[] data = new byte[1];

            RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();

            crypto.GetNonZeroBytes(data);
            size = maxSize;
            data = new byte[size];
            crypto.GetNonZeroBytes(data);
            StringBuilder result = new StringBuilder(size);

            foreach (byte b in data)
            {
                result.Append(chars[b % (chars.Length - 1)]);
            }
            return Session["AppContext"].ToString() + Page.User.Identity.Name.ToString() + result.ToString();
        }

        private string ValidateImage(HttpPostedFile myFile)
        {
            string msg = null;
            //6MB
            int FileMaxSize = 6291456;
            //Check Length of File is Valid or Not.
            if (myFile.ContentLength > FileMaxSize)
            {
                msg = msg + "File Size is Too Large. You are allowed only a maximum of 6MB per Image.";
            }
            //Check File Type is Valid or Not.
            if (!IsValidFile(myFile.FileName))
            {
                msg = msg + "Invalid File Type.";
            }
            return msg;
        }

        private bool IsValidFile(string filePath)
        {
            bool isValid = false;

            string[] fileExtensions = { ".BMP", ".JPG", ".PNG", ".GIF", ".JPEG" };

            for (int i = 0; i < fileExtensions.Length; i++)
            {
                if (filePath.ToUpper().Contains(fileExtensions[i]))
                {
                    isValid = true; break;
                }
            }
            return isValid;
        }

删除代码:

/// <summary>
        /// Delete all images. If there are no Images then by default NoImage.png is assigned. So skip deleting that image.
        /// </summary>
        /// <param name="dt"></param>
        protected void DeleteApp_ImagesById(DataTable dt)
        {
            if (dt.Rows[0][0].ToString() != "~/images/NoImage.png")
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    if (dt.Rows[0][i].ToString() != string.Empty)
                    {
                        string str = Regex.Replace(dt.Rows[0][i].ToString(), "~/", "");
                        File.Delete(Request.PhysicalApplicationPath.ToString() + Regex.Replace(str, "/", "\\").ToString());
                    }
                }
            }
        }

【问题讨论】:

  • 上传过程中发生的事情导致文件锁定?你能显示上传代码和删除代码吗?
  • @Steve 请参阅使用为上传和删除提供的代码编辑

标签: asp.net file-io ftp shared-hosting


【解决方案1】:

关于 Image.Save 的 docs on MSDN 表示该文件保持锁定状态,直到 Image 被释放。

所以我想以这种方式更改保存图像的代码

    private void SaveImageByCompressing(HttpPostedFile hpf, string filePath) 
    { 
        using(Image imgFromClient = Image.FromStream(hpf.InputStream))
        { 
            string SavetoFullPath = AppDomain.CurrentDomain.BaseDirectory + 
                                    filePath.Replace("~/", "").Replace("/", "\\"); 
            Image.GetThumbnailImageAbort myCallbackCompressed = 
                                    new Image.GetThumbnailImageAbort(ThumbnailCallback); 
            using(Image imageToSave= imgFromClient.GetThumbnailImage(imgFromClient.Width,
                                    imgFromClient.Height, myCallbackCompressed, IntPtr.Zero))
            {
                 imageToSave.Save(SavetoFullPath, System.Drawing.Imaging.ImageFormat.Jpeg); 
            }
        }
    } 


    public static void SaveThumbImage(string imagePath, string filePath, 
                                      int width = 0, int height = 0)   
    {   
        using(Image originalImage = Image.FromFile(imagePath))
        {
            if (width > 0 && height > 0)   
            {   
                Image.GetThumbnailImageAbort myCallback = 
                      new Image.GetThumbnailImageAbort(ThumbnailCallback);   
                using(Image imageToSave = originalImage.GetThumbnailImage(width, height, 
                                    myCallback, IntPtr.Zero))
                {
                    imageToSave.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);   
                }
            }   
            else   
            {   
                originalImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);   
            }   
        }   
     }

是一种确保您的图片在完成上传代码后立即解锁的安全方法

【讨论】:

    猜你喜欢
    • 2013-08-06
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 2018-01-10
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多