views:

310

answers:

8

I was using the CreateText method to create an empty file (as below) in "App1". Then tried to have another application write to that file but it failed b/c it was locked. It was not unlocked until I closed "App1"

File.CreateText(path)

To fix this I can do this:

Dim sw As StreamWriter = File.CreateText(path)
sw.Close()

Why does calling just CreateText lock the file? Is there some implicit streamwriter or filewriter or something being created?

tep

A: 

Yes, a StreamWriter is created. See the docs. I suggest having the first program to write to the file create it.

Matthew Flaschen
+5  A: 

Yes it does. CreateText() returns a StreamWriter object, which is open to the file that you specified.

If you just ignore the return value, that StreamWriter hangs around, holding onto your file. You really need to deal with it like in the second block of code.

womp
A: 

I think the simplest solution is to create a wrapper function which does the create and close for you.

Module Tools
  Sub CreateTextNoLock(ByVal text as String)
    Dim sw = File.CreateText(text)
    sw.Close
  End Sub
End Module
JaredPar
+2  A: 

CreateText() creates the file and then returns the StreamWriter so you can keep writing to the file if needed.

To close the file, you have to explicitly close the file (as in your example).

Justin Niessner
+1  A: 

If you need an empty file without a stream, try this:

File.WriteAllBytes(path, new byte[0]);
Rubens Farias
+1  A: 

Is there some implicit streamwriter or filewriter or something being created?

A StreamWriter is created, as demonstrated by your own code. That's why you can assign the return value to a variable of type StreamWriter.

This is the simplest way I know to create an empty file:

File.CreateText(path).Close()

EDIT:

Tested and confirmed to work.

Andy West
A: 

You need to enclose your StreamWriter in a using block to scope it out once the close is called. This will cause it to call it's dispose (closing it) and then unlink it as a reference and "send" it to the GC.

Using sw As StreamWriter = File.CreateText(path)
    sw.Write("")
End Using
Joel Etherton
+1  A: 

File.CreateFile, through StreamWriter, ends up calling the FileStream constructor passing FileMode.Create, FileAccess.Write and FileShare.Read. That's a very normal way to create, access and share files. You certainly would want write access since you just created the file. And it is sorta okay for other processes to read the file while you are writing it, nothing really bad happens when they do.

What you are asking for is possible, but you can't use File.CreateFile(). You'll have to first create a FileStream (Create, Write and FileShared.ReadWrite), and pass that to the StreamWriter constructor. Now the file can be written both by you and another process.

Which is rather tricky, suppose you and some other process both write to the file at the same time. That's first-come, first serve, the file will end up containing your program output, randomly mixed with the other process' output. It isn't very likely that the file will be readable after that happened.

Maybe you want to do something like intentionally not writing to the file yourself so this doesn't happen. It is very unusual, but it could be made to work. The bigger problem then would be for that other process to detect that the file is even there. Everything would probably work better if you just leave it up to the other process to create the file.

Hans Passant