Creating an empty file in C# - c#

What's the simplest/canonical way to create an empty file in C#/.NET?
The simplest way I could find so far is:
System.IO.File.WriteAllLines(filename, new string[0]);

Using just File.Create will leave the file open, which probably isn't what you want.
You could use:
using (File.Create(filename)) ;
That looks slightly odd, mind you. You could use braces instead:
using (File.Create(filename)) {}
Or just call Dispose directly:
File.Create(filename).Dispose();
Either way, if you're going to use this in more than one place you should probably consider wrapping it in a helper method, e.g.
public static void CreateEmptyFile(string filename)
{
File.Create(filename).Dispose();
}
Note that calling Dispose directly instead of using a using statement doesn't really make much difference here as far as I can tell - the only way it could make a difference is if the thread were aborted between the call to File.Create and the call to Dispose. If that race condition exists, I suspect it would also exist in the using version, if the thread were aborted at the very end of the File.Create method, just before the value was returned...

File.WriteAllText("path", String.Empty);
or
File.CreateText("path").Close();

System.IO.File.Create(#"C:\Temp.txt");
As others have pointed out, you should dispose of this object or wrap it in an empty using statement.
using (System.IO.File.Create(#"C:\Temp.txt"));

To avoid accidentally overwriting an existing file use:
using (new FileStream(filename, FileMode.CreateNew)) {}
...and handle the IOException which will occur if the file already exists.
File.Create, which is suggested in other answers, will overwrite the contents of the file if it already exists. In simple cases you could mitigate this using File.Exists(). However something more robust is necessary in scenarios where multiple threads and/or processes are attempting to create files in the same folder simultaneously.

You can chain methods off the returned object, so you can immediately close the file you just opened in a single statement.
File.Open("filename", FileMode.Create).Close();

A somewhat common use case for creating an empty file is to trigger something else happening in a different process in the absence of more sophisticated in process communication. In this case, it can help to have the file creation be atomic from the outside world's point of view (particularly if the thing being triggered is going to delete the file to "consume" the trigger).
So it can help to create a junk name (Guid.NewGuid.ToString()) in the same directory as the file you want to create, and then do a File.Move from the temporary name to your desired name. Otherwise triggered code which checks for file existence and then deletes the trigger may run into race conditions where the file is deleted before it is fully closed out.
Having the temp file in the same directory (and file system) gives you the atomicity you may want. This gives something like.
public void CreateEmptyFile(string path)
{
string tempFilePath = Path.Combine(Path.GetDirectoryName(path),
Guid.NewGuid.ToString());
using (File.Create(tempFilePath)) {}
File.Move(tempFilePath, path);
}

Path.GetTempFileName() will create a uniquly named empty file and return the path to it.
If you want to control the path but get a random file name you can use GetRandomFileName to just return a file name string and use it with Create
For example:
string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);

Related

How to create a directory in C# *only* if it doesn't already exist?

Directory.CreateDirectory creates a folder if it doesn't already exist, otherwise it just returns the DirectoryInfo for the already-existing folder.
But I want to make sure I create a new sub-folder every time a process is run (run1, run2, run3, etc). And multiple people may be running that process at once. So I can't do
if (!Directory.exists("run77"){CreateDirectory("run77");}
Because that has a race condition - someone else may create the folder in between those two calls.
Is there any way to ensure that I definitely get the next unused folder name?
The obvious answer: Don't use sequential IDs in this case. Use GUIDs instead. For things happening in multiple instances at once I rarely found sequential numbers helpful in that there isn't really an inherent sequence.
The other option would be to drop down to the Windows API where you can just try and re-try creating directories with increasing sequence numbers until the call succeeds, at which point you found your directory to work with.
This goes way beyond merely creating directories. You have multiple processes (on multiple machines even, maybe) that want to obtain a sequentially named resources, for themselves only.
If you definitely want to do this, you will have to synchronize it yourself. So either:
If the processes run on the same machine, use a machine-wide lock (e.g. Mutex) that synchronizes the directory creation code.
Create an out-of-process central authority (other than the filesystem itself) which provides the next number upon each successive, synchronized call.
Create a sentinel file / lock file containing a process-specific value, during the presence of which no other processes will try to create a directory, and remove it after creating the directory.
Apply filesystem permissions in such a way, that attempting to write into the given directory raises an error (if CreateDirectory() doesn't throw already). Then you'll have to assume that any permission error means a race condition occurred, and try to create the next directory.
All of those are brittle solutions.
One possible solution is to introduce a simple synchronization using exclusively opened file.
Here is possible implementation (as not fully thought code):
FileStream lock = null;
try
{
// someUniequeLockFileName - should be the same for all processes and unlikely to match real name in that folder
lock = File.Open(Path.Combine(currentFolder, someUniqueLockFileName), FileMode.Create, FileAccess.ReadWrite, FileShare.None);
... // you successfully obtain lock, can create subfolders
}
catch { }
finally
{
lock.Close();
}
One way is using a mutex which is an expensive call. However like most said if possible use sequential Ids instead. Here is an example using a mutex:
Mutex m = null
try
{
m = new Mutex(false, "CreateDirectoryMutex");
m.WaitOne();
if (!Directory.exists("run77"))
CreateDirectory("run77");
}
finally
{
if(m != null)
m.ReleaseMutex();
}

Do I need to explicitly close the StreamReader in C# when using it with string variable?

This is my code:
string data = "...";
var stream = new StreamReader(data);
Is that okay not call the Close() method?
Yes, otherwise you will have a memory leak. Wrap your StreamReader in a using statement so you don't have to worry about cleaning it up e.g.
using (var reader = StreamReader(data))
{
...
}
Have you actually compiled and run your code?
The StreamReader(string) constructor treats the input as a file name!
Unless this isn't really your code and you meant StringReader, your code is trying to stream the contents of the file name specified in data, which is likely to throw a FileNotFoundException because the file probably doesn't exist. And if it did, you would certainly need to call Close or integrate your code into a using statement to release the file handle.
You might also want to take a look at this tutorial on msdn:
http://msdn.microsoft.com/en-us/library/aa355056.aspx
which tells you about things you need to be careful with the using statement. Other than that, using is the way to go.
Another pretty good article on codeProject. Worth reading.
The resource will not be accessable to other processes until your process stops using it so you should close it if you don't need it

Problems with Streamwriter

I know it sounds really stupid, but I have a really easy application that saves some data from some users on a database, and then I want to write all the data on a .txt file.
The code is as follows:
List<MIEMBRO> listaMiembros = bd.MIEMBRO.ToList<MIEMBRO>();
fic.WriteLine("PARTICIPACIONES GRATUITAS MIEMBROS: ");
mi = new Miembro();
foreach (MIEMBRO_GRATIS m in listaMiembroGratis)
{
mi.setNomMiembro(m.nomMiembro);
mi.setNumRifa(m.numRifa.ToString());
fic.WriteLine(mi.ToString());
}
fic.WriteLine();
As you see, really easy code. The thing is: I show the information on a datagrid and I know there are lots of more members, but it stops writing in some point.
Is there any number of lines or characters to write on the streamwriter?? Why I can't write all the members, only part of them???
fic is probably not being flushed by the time you are looking at the output file; if you instantiate it as the argument for a using block, it will be flushed, closed, and disposed of when you are done.
Also, in case you are flushing properly (but it is not being flushed by the time you are checking the file), you could flush at the end of each iteration:
foreach (MIEMBRO_GRATIS m in listaMiembroGratis)
{
mi.setNomMiembro(m.nomMiembro);
mi.setNumRifa(m.numRifa.ToString());
fic.WriteLine(mi.ToString());
fic.Flush();
}
This will decrease performance slightly, but it will at least give you an opportunity to see which record is failing to write (if, indeed, an exception is being thrown).
Is there any number of lines or characters to write on the
streamwriter??
No, there isn't.
As you see, really easy code. The thing is: I show the information on
a datagrid and I know there are lots of more members, but it stops
writing in some point
My guess is that your code is throwing an exception and you aren't catching it. I would look at the implementation of setNomMiembro, setNumRifa and ToString in Miembro; which, by the way, in the case of setNomMiembro and setNumRifa should probably be implemented as properties ({get;set;}) and not as methods.
For example, calling ToString in numRifa would throw a null pointer exception if numRifa is null.

How to know if an unexisting file can be created without trying to create it and catching an IOException

I know this question has been asked before (actually, i found many instances of more or less the same question but with no satisfying solution yet),but i'm gonna rephrase it a little differently..
I want to use FileInfo to get an indication of whether or not i can create a (new) file on a specific disk (hard disk/usb card/etc.) and directory.
The current problems I'm facing:
If the file that I want to create is located on a write-protected disk/USB card/etc. - An IOException will be thrown, only the problem is that it will be thrown after a certain delay (probably after the Flush() was invoked)
Since the file I want to create does not exist, FileInfo.IsReadOnly will always return true, even if the given path is not actually write-protected !
It will return false only in case where the file already exists and is not readonly.
So how can i know if it is possible to create a specific file BEFORE trying to actually create it ?
thanks..
This intrigued me enough to give it a go, albeit without thorough or much testing at all, here are a couple of things you might want to work with (lookout for exceptions too!):
static bool CanCreateFile(FileInfo fileInfo)
{
if (fileInfo.Exists) return false;
return !fileInfo.Attributes.HasFlag(FileAttributes.ReadOnly);
}
static bool CanCreateFile2(FileInfo fileInfo)
{
if (fileInfo.Exists) return false;
return IsDirectoryWriteable(
Path.GetDirectoryName(fileInfo.FullName));
}
static bool IsDirectoryWriteable(string path)
{
var directoryInfo = new DirectoryInfo(path);
if (!directoryInfo.Exists)
{
return IsDirectoryWriteable(directoryInfo.Parent.FullName);
}
return !directoryInfo.Attributes.HasFlag(FileAttributes.ReadOnly);
}
But as stated in another answer, there is really no guarantee that when you actually return from 'validation' that something won't happen to change the validity of the situation before your next action of writing.
In general no. Even if you could the conditions might change between you do the check and you try to create the file. E.g. the user removes a thumb drive or someone changes file permissions.
But you can build a pretty good estimate by looking at the DirectoryInfo for the parent directory.
Check DirectoryInfo.Attributes for FileAttributes.ReadOnly and traverse all ACL:s in DirectoryInfo.GetAccessControl() to find out if the current user has enough permissions.
I guess it is much easier to just try to create the file and catch the exception.

c# Writing to a file without using using{}

I'm writing a little application whereby I want to write the results of the operations to a file.
Basically what I want to do is open a stream to a file (I'm thinking FileStream, but am open to suggestions), write data to the file, then close it at a later date.
So I've got a class called ReportFile, with methods:
.Create( string path )
.WriteInfo( string a, string b, string c ) ; //Or something like this...
//Then sometime in the future
.Close()
So the class using the ReportFile class will create an instance, call WriteInfo(..) multiple times until it is finished doing whatever it needs to do, then call Close() at some point in the future.
Now I know I need to implement a Dispose pattern on the ReportFile class to ensure that if anything goes screwey that the handle to the file gets appropriately dealt with.
However I haven't been able to find anything thus far on the interweb showing a good way of keeping the file open and then checking to see if it needs to be closed, most of the examples just open the file do the writing, then close it - all within a using{} construct.
In the ReportFile class I want to be able to check if the FileStream instance is not closed so that I can close it and free up resource.
Anyone know of a good link to reference or any other advice ?
(Ohh I should mention that I don't do C# full time, it's only a hobby thing, so if this is a dumb question, my apologies ;-)
Is there a particular reason that you have to keep the file open?
In this situation I would simply open the file each time using FileMode.Append (or pass append=true to StreamWriter ctor) and then close it again afterwards with a using. eg:
void WriteInfo(string text)
{
// Second parameter to StreamWriter ctor is append = true
using(StreamWriter sw = new StreamWriter(logFilePath, true))
{
sw.WriteLine(text);
}
}
Taking this approach you can don't really need a Create() or Close() method. The append=true will create the file if it does not exist.
The ReportFile would just have a TextWriter instance variable - which you would dispose within your own Dispose() method.
Why do you want to have an explicit Close() method, btw? Your callers should be using a using statement anyway, so why would they want to explicitly call Close as well?
Justa, i think that you're overthinking this feature a bit. The reason that you're seeing examples with the using construct is that using{} with file write is quite fast and safe.
Chances are that you're not opening and closing the file several times a second so there's no need to keep it open all the time and thus risking leaving the app without closing the file (which is a PITA to fix after the fact.) Using the using construct makes certain that the resource, your file in this case, is released and closed properly.
Another piece of advice for programming: don't worry about efficiency at the outset. Get it working first the simplest way you can and improve speed/performance later only if it's necessary.
public void Create(string path) {
mStream = new FileStream(path);
}
public void Dispose() {
if (mStream != null)
mStream.Dispose();
}
I would suggest using the "using" construct and keep the file open only whilst saving.
An idea might be to build the content in memory then save it when you're ready. using a StringBuilder for example.
In the case you simply won't use a using {} construct, you can use the IDisposable interface: http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

Categories

Resources