System.IO.File.Create locking a file - c#

I'm using System.IO.File.Create to create a file. I'm not writing to it with a stream writer, just creating it.
I get a server error in the front end when the application tries to open the newly created file - that the file is in use. Garbage collection then seems to come along and a few minutes later all is OK.
Now I know if I was using Streamwriter I would have to close it. Does the same apply to creating?
I've read that opening a stream writer to the file then immediately closing it will fix this, but it seems messy. Is there a simpler way?

Try this:
System.IO.File.Create(FullFName).Close();

File.Create returns a FileStream. You should use it like this:
using (FileStream fs = File.Create(path))
{
//you can use the filstream here to put stuff in the file if you want to
}

Creating the file opens a FileStream to it, hence, locking it (File.Create returns the FileStream).
You must close this stream in order to access the file. This is best done with a using statement:
using(FileStream fs = File.Create(path))
{
}

When using File.Create you get a FileStream returned. Until you either close the stream or until the FileStream object is disposed (by the garbage collector's finaliser) it will remain open and locked.
FileStream implements IDisposable so you can do the following:
using(FileStream fs = File.Create(filename))
{
// Do stuff like write to the file
}
The using statement is "syntactic sugar" and causes the compiler to generate code that is functionally equivalent to:
FileStream fs = File.Create(filename)
try
{
// Do stuff like write to the file
}
finally
{
fs.Dispose();
}
The Dispose method calls Close internally.

I was using:
System.IO.File.Create(sFullFileName);
The above .Create method was not closing the file
I now use:
System.IO.File.WriteAllText(sFullFileName, "Uploading");
This method creates and closes the file (note: I put a string "Uploading" in the file, but i'm sure string.Empty will also work.

The Create method will return a file handle. The file handle should be closed before re-using the file. Please see details in the MSDN article File.Create Method (String).
Summary:
The FileStream object created by this method has a default FileShare value of None; no other process or code can access the created file until the original file handle is closed.

Related

The file is being used by another process, I must close it? How?

I am using a text file to have some data there for later purposes. So what I do is to check if file exists, if not I am creating a new file when I need. This gives me error saying that my file is still being used by a different process, but I'm not sure why that is.
This is how I do it. Here, I am checking if file exists which starts when program runs:
private void CreateLastOpenFile()
{
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (!File.Exists(file))
{
File.Create(file);
}
}
Now, I am adding some data to it while checking or creating a new file (I am having this in 2 places in my program):
CreateLastOpenFile();
File.WriteAllText(file, data);
What could be wrong here? I have read some examples from the Net, but didn't see anything about closing any files.
Try this. This will close the opened stream during file creation
if (!File.Exists(file))
{
FileStream str = File.Create(file);
str.Close();
}
File.Create is creating a FileStream that locks the file. You should close it. Actually, you don't even need to create a file. File.WriteAlltext will do it for you
You are not closing the stream handle that File.Create() returns.
Suggest you do not use File.Create() in your case. You can just use File.WriteAllText(file, data); - according to MSDN documentation it creates the file if it doesn't exist or overwrites the contents when file exists. After that closes the file stream.
I recommend you to create and fill with data the file in one step, using some class like StreamWriter that allows you to dispose the class, you should not have problem doing it this way, here is an example:
StreamWriter Swr = new StreamWriter(FilePath);
Swr.Write(Data);
Swr.Close();
Swr.Dispose();
//Doing the close and Dispose you get sure the file is not locked anymore
You can also use File.WriteAllText(string Path, string Data), this method does not lock the file.
If you are using below method to write the data into text file, you dont need to check if file exists and if not create it. "WriteAllText" takes cares of all these things by itself. It will create the file if not exists, write the data and close it, or overwrite the file if already exists.
File.WriteAllText(file, data);
if you are using writeAllText() or readAllText() method than close() method is not used as they closed file after reading or writing(above methods)

Clear the Contents of a File

How does one clear the contents of a file?
You can use the File.WriteAllText method.
System.IO.File.WriteAllText(#"Path/foo.bar",string.Empty);
This is what I did to clear the contents of the file without creating a new file as I didn't want the file to display new time of creation even when the application just updated its contents.
FileStream fileStream = File.Open(<path>, FileMode.Open);
/*
* Set the length of filestream to 0 and flush it to the physical file.
*
* Flushing the stream is important because this ensures that
* the changes to the stream trickle down to the physical file.
*
*/
fileStream.SetLength(0);
fileStream.Close(); // This flushes the content, too.
Use FileMode.Truncate everytime you create the file. Also place the File.Create inside a try catch.
The easiest way is:
File.WriteAllText(path, string.Empty)
However, I recommend you use FileStream because the first solution can throw UnauthorizedAccessException
using(FileStream fs = File.Open(path,FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
lock(fs)
{
fs.SetLength(0);
}
}
Try using something like
File.Create
Creates or overwrites a file in the
specified path.
The simplest way to do this is perhaps deleting the file via your application and creating a new one with the same name... in even simpler way just make your application overwrite it with a new file.

My C# app is locking a file, how I can find where it does it?

I'm writing code that check files path calculate hash (SHA1) and copy them.
I made sure that I do not lock them like for example using
public static string SHA1(string filePath)
{
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var formatted = string.Empty;
using (var sha1 = new SHA1Managed())
{
byte[] hash = sha1.ComputeHash(fs);
foreach (byte b in hash)
{
formatted += b.ToString("X2");
}
}
return formatted;
}
So how I can, in Visual Studio, find where it does lock the file?
Can you keep the above syntax as and give a try?
using(var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
//Your code goes here.
}
There is a little windows soft : process explorer and in this you can find which process has an handle on a file :
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Locking usually happens whenever you create a file stream on a file without later closing that stream. Unless you call fs.Close(); in your code, your application will keep the file open (and thus locked).
You could wrap this in a try-finally block or try the code that Siva Gopal posted.
You assumption that opening the file stream with just FileAccess.Read will not lock the file is faulty; the file is locked while it has been opened for a file operation and has not been closed.
A FileStream does not close an opened file until the FileStream is garbage collected or you explicitly call its Close or Dispose method. Either insert such an explicit call as soon as you are done with the file you opened, Or wrap the use of the FileStream in a using statement, which implies the call to Dispose, like other answers suggest.

Dataset ReadXML method Stream vs. String

I have code that calls the ReadXml method of the DataSet class and passes in a file name ReadXml(strFileName). Occasionally this throws a System.IO.IOException because the file is being used by another process.
If I change the code to use the ReadXml(stream) method and pass in a FileStream like this:
using(FileStream fs = new FileStream(this.filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ))
{
MyDS.ReadXxml(FileStream);
}
Will that prevent the IOException from occuring? What is going on under the hood when you simply pass in a file name?
The DataSet class will create a FileStream object for you if you pass in the filename as a string. The overloaded method that takes a Stream as a parameter allows you to pass in a Stream object if you have one instead of a filename.
The version that takes a string as a parameter will simply create a FileStream and pass that onto the version that takes a Stream as a parameter.
You should use the overload that suits the data you have. In this case the string.
Most likely, they both open a FileStream and pass it to XmlReader.Create, then use the XmlReader to process the data.
"Occasionally this throws a System.IO.IOException because the file is being used by another process."
As you said, it's throwing an Exception because the file is being used by another process. Nothing you can do about that - stop the other process from using the file and it will work again.
If you believe this is false, then you should check that all your FileStreams are correctly closed, using the using construct as you are in the question.
Hope that helps.

Program crashes after trying to use a recently created file. C#

So here is my code
if (!File.Exists(pathName))
{
File.Create(pathName);
}
StreamWriter outputFile = new StreamWriter(pathName,true);
But whenever I run the program the first time the path with file gets created. However once I get to the StreamWriter line my program crashes because it says my fie is in use by another process. Is there something I'm missing between the File.Create and the StreamWriter statements?
File.Create doesn't just create the file -- it also opens it for reading and writing. So the file is indeed already in use when you try to create the StreamWriter: by your own process.
StreamWriter will create the file specified by pathName if it doesn't exist, so you can simply remove the File.Exists check and simplify your your code this:
using (var writer = new StreamWriter(pathName, true))
{
// ...
}
From MSDN:
StreamWriter Constructor (Stream)
Initializes a new instance of the StreamWriter class for the specified file [...]. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.
As others have mentioned, File.Create is creating a FileWriter that's holding your file open. But aside from that, there's no reason to check for file existence before trying to open the file. Just tell File.Open to open an existing file if one is there:
var outputFile = new StreamWriter(File.Open(pathName, FileMode.OpenOrCreate));
After the File.Create the stream is still open.
You could use:
File.Create(pathName).Close();
This creates the file and closes it directly.
More accepted is:
using (var file = File.Create(pathName)) {
// use the file here
// it will be closed when leaving the using block
}
Also: Why do you create a file, that you create 2 lines further in your code? The StreamWriter constructor (with append=true) will create or append the file if it does not exist.
File.Create returns a FileStream. Why don't you save that and pass it to the StreamWriter constructor instead of passing a pathname?

Categories