136

I'm trying to detect if a file exists at runtime, if not, create it. However I'm getting this error when I try to write to it:

The process cannot access the file 'myfile.ext' because it is being used by another process.

string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
if (!File.Exists(filePath)) 
{ 
    File.Create(filePath); 
} 

using (StreamWriter sw = File.AppendText(filePath)) 
{ 
    //write my text 
}

Any ideas on how to fix it?

bluish
  • 26,356
  • 27
  • 122
  • 180
Brett
  • 1,923
  • 3
  • 18
  • 24

11 Answers11

165
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

I want to update this answer to say that this is not really the most efficient way to write all text. You should only use this code if you need something quick and dirty.

I was a young programmer when I answered this question, and back then I thought I was some kind of genius for coming up with this answer.

Carsen Daniel Yates
  • 1,962
  • 1
  • 11
  • 16
  • 4
    I love how all the other answers were just way too complicated. People don't realize that there is a simpler answer to every problem. – Carsen Daniel Yates Nov 23 '11 at 01:08
  • 15
    The downside to this code is that it unnecessarily opens the file twice. Also, it isn't really necessary to check whether the file exists at all, as the FileStream constructor will automatically create it for you if it does not exist, unless you explicitly tell it not to do that. – reirab Aug 09 '13 at 14:02
  • 2
    @reirab This is completely relative. I need to check if the file exists and if it does, delete it and create it again, so this answer is preferred in my case. – makoshichi Apr 13 '16 at 13:54
  • 1
    @S.O. Then you have a different problem than the OP, just a related one. Also, in your case, you can still just use the `FileStream(string, FileMode)` constructor and pass it [FileMode.Create](https://msdn.microsoft.com/en-us/library/system.io.filemode(v=vs.110).aspx), which will overwrite any existing file. Still no need to open the file twice. Also, this answer was edited after I posted my original comment. – reirab Apr 13 '16 at 14:23
  • simple.. but very useful – Sobhan Nov 17 '16 at 15:36
  • 2
    Point of this answer is to show you can just add `.Close()` on the end, so it works in any case. I distrust the system of using `FileStream` for everything because I don't want the exception to happen on `FileMode.Create` that the file is already there - especially when I want to clear the contents and not append to them through `FileMode.Open`. To me, `FileStream` only really works after getting rid of the file in question, then writing to it. Since `File.Create` is leaving it open and locked, it seems adding `.Close()` to it is the only real way to deal with my scenario and S.O.'s. – vapcguy Nov 23 '16 at 17:05
  • But this is completely pointless! Why bother `File.Create()` in the first place? Also, the signature for [`File.WriteAllText()`](https://msdn.microsoft.com/en-us/library/system.io.file.writealltext%28v=vs.110%29.aspx) says it accepts two or three arguments, not one. – binki Nov 29 '16 at 18:45
  • Though it may solve your particular problem, most of the times, a simple answer hides a bad practice behind it, that will kick back in the future. When many approaches solve your problem, you should always pick and use the proper one, not the fastest one. The one that is chosen as the right answer seems simpler to me than this one here. You open and close a file, then re-open to write to it. Where is the simplicity? What is more simple than saying "Write this text to that file. Append it if the file exists"? – Thanasis Ioannidis Jul 13 '18 at 07:08
  • I updated my answer adding explaining that it's not an efficient way to solve the problem. Thanks for your input. I answered this question years ago and I was quite the newb back then. – Carsen Daniel Yates Nov 24 '18 at 03:50
  • `File.Create(FilePath).Close();` helped me to "release" the resources so that the file can be used by WinSCP. – Lukas G Jan 22 '19 at 22:10
130

The File.Create method creates the file and opens a FileStream on the file. So your file is already open. You don't really need the file.Create method at all:

string filePath = @"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))
{
    //write to the file
}

The boolean in the StreamWriter constructor will cause the contents to be appended if the file exists.

bluish
  • 26,356
  • 27
  • 122
  • 180
Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
  • i tried the above code but i am getting the same error when the file is created and when it tries to write in to the file it shows file is being used by other process. – Anmol Rathod Jul 15 '18 at 20:58
  • 1
    @AnmolRathod go sure that you don't use `File.Create()` method! The snippet above already creates the file! – Daniel Eisenreich Aug 15 '18 at 13:25
27

When creating a text file you can use the following code:

System.IO.File.WriteAllText("c:\test.txt", "all of your content here");

Using the code from your comment. The file(stream) you created must be closed. File.Create return the filestream to the just created file.:

string filePath = "filepath here";
if (!System.IO.File.Exists(filePath))
{
    System.IO.FileStream f = System.IO.File.Create(filePath);
    f.Close();
}
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{ 
    //write my text 
}
Ralf de Kleine
  • 11,464
  • 5
  • 45
  • 87
  • I don't seem to have a close option. Here's the code: string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); if (!File.Exists(filePath)) { File.Create(filePath); } using (StreamWriter sw = File.AppendText(filePath)) { //write my text } – Brett May 06 '10 at 13:23
  • `File.Create` returns `FileStream` and that has `Close()` – Null Head Sep 07 '15 at 20:49
15
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
user3430377
  • 167
  • 1
  • 2
9

File.Create returns a FileStream. You need to close that when you have written to the file:

using (FileStream fs = File.Create(path, 1024)) 
        {
            Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
            // Add some information to the file.
            fs.Write(info, 0, info.Length);
        }

You can use using for automatically closing the file.

kimtiede
  • 202
  • 1
  • 8
  • Though the OP is trying to open a [`StreamWriter`](https://msdn.microsoft.com/en-us/library/system.io.streamwriter(v=vs.110).aspx) as can be inferred from his use of [`File.AppendText`](https://msdn.microsoft.com/en-us/library/system.io.file.appendtext%28v=vs.110%29.aspx). – binki Nov 29 '16 at 18:55
9

I updated your question with the code snippet. After proper indenting, it is immediately clear what the problem is: you use File.Create() but don't close the FileStream that it returns.

Doing it that way is unnecessary, StreamWriter already allows appending to an existing file and creating a new file if it doesn't yet exist. Like this:

  string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
  using (StreamWriter sw = new StreamWriter(filePath, true)) {
    //write my text 
  }

Which uses this StreamWriter constructor.

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

I know this is an old question, but I just want to throw this out there that you can still use File.Create("filename")", just add .Dispose() to it.

File.Create("filename").Dispose();

This way it creates and closes the file for the next process to use it.

IamBatman
  • 975
  • 12
  • 18
  • 2
    `File.Create(FilePath).Close();` from the answer above has `this.Dispose(true); GC.SuppressFinalize((object) this);` in its implementation. – Lukas G Jan 22 '19 at 22:12
1

I think I know the reason for this exception. You might be running this code snippet in multiple threads.

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • For me was the problem that i write a log file on asyncron way (in a different thread: Task.Run() without waiting (on purpose), and this cause multithread access to the same file. – Bence Végert Mar 19 '19 at 17:36
1

This question has already been answered, but here is a real world solution that checks if the directory exists and adds a number to the end if the text file exists. I use this for creating daily log files on a Windows service I wrote. I hope this helps someone.

// How to create a log file with a sortable date and add numbering to it if it already exists.
public void CreateLogFile()
{
    // filePath usually comes from the App.config file. I've written the value explicitly here for demo purposes.
    var filePath = "C:\\Logs";

    // Append a backslash if one is not present at the end of the file path.
    if (!filePath.EndsWith("\\"))
    {
        filePath += "\\";
    }

    // Create the path if it doesn't exist.
    if (!Directory.Exists(filePath))
    {
        Directory.CreateDirectory(filePath);
    }

    // Create the file name with a calendar sortable date on the end.
    var now = DateTime.Now;
    filePath += string.Format("Daily Log [{0}-{1}-{2}].txt", now.Year, now.Month, now.Day);

    // Check if the file that is about to be created already exists. If so, append a number to the end.
    if (File.Exists(filePath))
    {
        var counter = 1;
        filePath = filePath.Replace(".txt", " (" + counter + ").txt");
        while (File.Exists(filePath))
        {
            filePath = filePath.Replace("(" + counter + ").txt", "(" + (counter + 1) + ").txt");
            counter++;
        }
    }

    // Note that after the file is created, the file stream is still open. It needs to be closed
    // once it is created if other methods need to access it.
    using (var file = File.Create(filePath))
    {
        file.Close();
    }
}
Halcyon
  • 14,631
  • 17
  • 68
  • 99
0

you can just use using keyword around File.Create(path) to finalize the process using(File.Create(path));

-2

Try this: It works in any case, if the file doesn't exists, it will create it and then write to it. And if already exists, no problem it will open and write to it :

using (FileStream fs= new FileStream(@"File.txt",FileMode.Create,FileAccess.ReadWrite))
{ 
     fs.close();
}
using (StreamWriter sw = new StreamWriter(@"File.txt")) 
 { 
    sw.WriteLine("bla bla bla"); 
    sw.Close(); 
 } 
gyousefi
  • 306
  • 3
  • 9