locked
Need help with System.IO.IOException on file.SaveAs (File Upload) RRS feed

  • Question

  • User-666661156 posted

    Hey Everyone, 

    I recently started getting an error on a file upload piece of code that worked previously. It does work currently in some environments, but just not on my machine or on some test servers. The error that I get is "The process cannot access the file (Filename) because it is being used by another process". Basically the file first gets uploaded to a folder within the application before it gets uploaded to a web service. Here is my code (the highlighted line is where the error occurs): 

      if (file != null && file.ContentLength > 0)
                        {
    
                            //Convert file to Base64binary for upload using web services
                            string fileNameResult = Path.GetFileName(file.FileName);
                            bool exists = System.IO.Directory.Exists(Server.MapPath("~/Uploads"));
                            if (!exists)
                            {
                                System.IO.Directory.CreateDirectory(Server.MapPath("~/Uploads"));
                            }
                            file.SaveAs(System.IO.Path.Combine(Server.MapPath("~/Uploads"), fileNameResult));
                            string FilePath = Server.MapPath("~/Uploads") + "\\" + fileNameResult;
                            FileInfo fInfo = new FileInfo(FilePath);
                            long numBytes = fInfo.Length;
                            //FileStream fStream = new FileStream(file.FileName, FileMode.Open, FileAccess.Read);
                            FileStream fStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                            BinaryReader br = new BinaryReader(fStream);
                            byte[] data = br.ReadBytes(Convert.ToInt32(numBytes));
    
                            //Upload the File
                            System.Xml.XmlNode xmlUploadResult;
                            Service dsWSdev = new Service();
                            xmlUploadResult = dsWSdev.ApplyUpload("AppUserDev", "Pass4word", "DocuShare", String.Empty, String.Empty, false, CollectionPathSAT, ConfirmationNumber + "-" + fileNameResult, data);
    
                            //Check Upload Result, If Result is not 200 then an error occurred. 200 OK
                            string strResult = xmlUploadResult.FirstChild.InnerText.ToString();
    
                            if (strResult != "200")
                            {
                                // create the error message
                                throw new ArgumentException("Error uploading the document: " + xmlUploadResult.InnerText.ToString());
                            }
                            else
                            {
                                strResult2 = xmlUploadResult.InnerText;
                                string splithhandle = strResult2.Split('-').Last(); 
                                docushareFileLink += staticURL + splithhandle + "/" + fileNameResult + ", ";
                            }
                            fStream.Flush();
                            br.Close();
                            fStream.Close();
                            if (strResult == "200")
                            {
                                System.IO.File.Delete(FilePath);
                            }
                            
    
                        }

    Any ideas ? I'm not sure why it stopped working all of a sudden, I even added Full Access to the folder through the security settings. Appreciate any help, thanks!

    Tuesday, March 5, 2019 8:43 PM

All replies

  • User475983607 posted

    The error generally indicates a stream is not properly disposed.  Use "using" statements around stream resources.

    Tuesday, March 5, 2019 8:51 PM
  • User-666661156 posted

    I'm not sure why it works in some instances. Any idea on how I can dispose the stream ? 

    Tuesday, March 5, 2019 8:53 PM
  • User475983607 posted

    I'm not sure why it works in some instances. Any idea on how I can dispose the stream ? 

    Use "using" statements around stream resources.  

    There is no indication what the file is named.

    string fileNameResult = Path.GetFileName(file.FileName);

    Never use the file name from the user input.

    Tuesday, March 5, 2019 8:57 PM
  • User-666661156 posted

    rankone

    I'm not sure why it works in some instances. Any idea on how I can dispose the stream ? 

    Use "using" statements around stream resources.  

    There is no indication what the file is named.

    string fileNameResult = Path.GetFileName(file.FileName);

    Never use the file name from the user input.

    As these are documents that the User uploads, I have to use the file name from the file input control unfortunately. So such as: 

        foreach (var file in files)
                    {
                    }

    The error occurs before the file stream though, at the file.SaveAs line. So should I be enclosing that in a using statement ? Moreover, how as I can't set it to a variable. 

    Tuesday, March 5, 2019 9:27 PM
  • User475983607 posted

    See the openly published docs for proper file name handling,  

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.fileupload.saveas?view=netframework-4.7.2

    Hopefully, this will fix the issue  Otherwise, you'll need to add better exception handling to figure out what's going on.

    Tuesday, March 5, 2019 9:31 PM
  • User303363814 posted

    I'm guessing that you have a button on a page that is called 'Upload' or something similar which triggers the process you have shown.

    what would happen if a user double-clicked that button?  Or clicked it twice in quick succession?

    Perhaps you need to disable the button as soon as it is clicked to prevent a file being uploaded again before it has been processed.

    Just a thought

    Tuesday, March 5, 2019 10:02 PM
  • User-666661156 posted

    I'm guessing that you have a button on a page that is called 'Upload' or something similar which triggers the process you have shown.

    what would happen if a user double-clicked that button?  Or clicked it twice in quick succession?

    Perhaps you need to disable the button as soon as it is clicked to prevent a file being uploaded again before it has been processed.

    Just a thought

    It's being done through HTTPPost on form submit. So the upload only happens once. 

    Tuesday, March 5, 2019 10:23 PM
  • User475983607 posted
    Does not stop a double tap.
    Tuesday, March 5, 2019 11:02 PM
  • User-666661156 posted

    Does not stop a double tap.

    I can look in to it, what would you recommend I do to prevent the double tap. Basically on the submit button a confirmation box pops up. When confirmed, the submit is executed, so that's the process I'm currently working with. 

    Tuesday, March 5, 2019 11:11 PM
  • User475983607 posted

    I can look in to it, what would you recommend I do to prevent the double tap. Basically on the submit button a confirmation box pops up. When confirmed, the submit is executed, so that's the process I'm currently working with. 

    Use JavaScript to disable a second click.  IMHO, you need to come up with a troubleshooting plan and that probably revolves around crafting a more detailed error message so you know what's going on at the time of the error.

    Tuesday, March 5, 2019 11:22 PM
  • User-1716253493 posted

    Seem like the file still uploading at the moment

    Try check, if the file is in use to avoid error

    https://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use

    protected virtual bool IsFileLocked(FileInfo file)
    {
        FileStream stream = null;
    
        try
        {
            stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (IOException)
        {
            //the file is unavailable because it is:
            //still being written to
            //or being processed by another thread
            //or does not exist (has already been processed)
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }
    
        //file is not locked
        return false;
    }

    or simply use try-catch block to skip it

    Wednesday, March 6, 2019 2:48 AM