0

「SampleApplication」という名前のWebサイトを介してアップロードした画像を削除しようとすると、スタックトレースに次のエラーが表示されます。

 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());
                    }
                }
            }
        }
4

1 に答える 1

1

Image.Saveに関する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);   
            }   
        }   
     }

アップロードコードを終了したときに画像のロックがすぐに解除されるようにするための安全な方法です

于 2012-09-01T09:16:46.557 に答える