简体   繁体   中英

C# The process cannot access file 'XYZ' because it is being used by another process

I am been fighting with this problem the last couple of days, it works fine when I am on my dev machine, but on the client it is showing this error.

Now this is the code that I have that seems to be showing the error so any help or guidance would be amazing, thank you in advance.

 private void document()
 {
         StreamWriter sWrite = new StreamWriter("C:\\Demo\\index.html");
         //LOTS OF SWRITE LINES HERE
         sWrite.Close();
         System.Diagnostics.Process.Start("C:\\Demo\\index.html");
 }

So I have no idea what it keeps telling me the file is already being used by another process if I run this method twice.

here is what you can do for example before trying to open the file from the Process.Start

var path = @"C:\Demo\index.html";
using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs))
{
    sw.WriteLine("Your contents to be written go here");
}
System.Diagnostics.Process.Start(path);

Some of it depends on the exact behavior. This could be for a few reasons: it could be, for example, due to an exception. The following code will produce the exception you've described.

for (int i = 0; i < 10; i++)
        {
            const string path = @"[path].xml";

            try
            {
                // After the first exception, this call will start throwing
                // an exception to the effect that the file is in use
                StreamWriter sWrite = new StreamWriter(path, true);

                // The first time I run this exception will be raised
                throw new Exception();

                // Close will never get called and now I'll get an exception saying that the file is still in use
                // when I try to open it again. That's because the file lock was never released due to the exception
                sWrite.Close();
            }
            catch (Exception e)
            {

            }
                //LOTS OF SWRITE LINES HERE

            Process.Start(path);
        }

A "using" block will fix this because it's equivalent to:

try
{
   //...
}
finally
{
   stream.Dispose();
}

In the context of your code, if you're doing a whole bunch of line writes it actually does make sense to consider if (and when) you want to call Flush at some point. The question is whether the write should be "all or none" - ie if an exception occurs, do you want the previous lines to still be written? If not, just use a "using" block - it'll call "Flush" once at the end in the "Dispose." Otherwise, you can call "Flush" earlier. For example:

using (StreamWriter sw = new StreamWriter(...))
{
    sw.WriteLine("your content");
    // A bunch of writes
    // Commit everything we've written so far to disc
    // ONLY do this if you could stop writing at this point and have the file be in a valid state.
    sw.Flush();

   sw.WriteLine("more content");
   // More writes
} // Now the using calls Dispose(), which calls Flush() again

A big possible bug is if you're doing this on multiple threads (especially if you're doing a lot of writes). If one thread calls your method and starts writing to the file, and then another thread calls it too and tries to start writing to the file as well, the second thread's call will fail because the first thread's still using the file. If this is the case, you'll need to use some kind of lock to make sure that the threads "take turns" writing to the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM