"releasing" a file..

FlyBoy

Well-known member
Joined
Sep 6, 2004
Messages
106
in my form_load sub...im trying to make a procedure which reads all the user names from a file using the streamreader and then putting them all into a listbox.
all works fine...unless when the file does not exitst.
so i tried the following thing(in the form load):

if file.exist("c:\1.txt")=false then
file.create("c:\1.txt")
else
dim fs as new filestream("c:\1.txt")
** the file to listbox procedure **
end if

then when im trying to get into the file again,to read or write from the program it says that its already being used....(i guess by the "file.create" actually im sure..)
any idea how to release it from this file.create???
 
This is not a good idea.

This is really unefficient programming. Doing this might cause some slowdown if theres a lot to release.

Better let the framework do the job when needed.
 
I didnt see any issues on efficiency asked from FlyBoy. Why is it not implementable?

anyway, FlyBoy, you can do fs.Close after the codes for releasing the resource on file.

I was just giving answer based on the question.. hehe...
 
Generally speaking you are better letting .Net manage the Garbage Collection process - it pretty much tunes itself to the available resources / memory usage patterns of your application and forcing a collection can interfere with this.
If you really must for a collection then GC.Collect() forces a full gartbage collection which can take a long time to complete and also have the side effect that some resources may now take longer to be released than if you hadnt forced collection, trying something like GC.Collect(0) may be a bit easier on the system.

A better plan is that if a class exposes a Close / Dispose method then calling that function when you are finished with the object will release critical resources, close the file / db connection / etc
 
FlyBoy said:
in my form_load sub...im trying to make a procedure which reads all the user names from a file using the streamreader and then putting them all into a listbox.
all works fine...unless when the file does not exitst.
so i tried the following thing(in the form load):

if file.exist("c:\1.txt")=false then
file.create("c:\1.txt")
else
dim fs as new filestream("c:\1.txt")
** the file to listbox procedure **
end if

then when im trying to get into the file again,to read or write from the program it says that its already being used....(i guess by the "file.create" actually im sure..)
any idea how to release it from this file.create???
File.Create(String) Returns a Stream, in the code provided, you dont close the stream returned to you, and thats why the file wasnt released. No amount of calls to GC.Collect will solve the problem.
 
Jay1b said:
Sorry to hijack the thread. But whats the difference between Filestream and Streamreader?


Ripped from the docs

MSDN Documentation said:
StreamReader is designed for character input in a particular encoding, whereas the Stream class is designed for byte input and output.

So if youre going to be reading from a stream that you know is text, one would most likely use a StreamReader over a FileStream.
 
This is C# but I figure the code should be roughly the same for VB.NET.
Whenever I deal with filestreams I always use the same structure of code:

FileStream fs = null;
TextWriter writer = null;
try
{
fs = new FileStream(somePath, FileMode.Create);
writer = new StreamWriter(fs);
writer.Write("Some Stuff");
/// put more useful stuff here
}
finally
{
if(writer!= null)
{
writer.Close();
}
if(fs!=null)
{
fs.Close();
}
}

No matter what happens in the code the stream will be closed as it is within the finally braces.
The error will no longer occur, additionally if you have the problem with one of your files in windows if you log out and log back in it will clear all the filestreams.
 
TamuTamu said:
This is C# but I figure the code should be roughly the same for VB.NET.
Whenever I deal with filestreams I always use the same structure of code:

FileStream fs = null;
TextWriter writer = null;
try
{
fs = new FileStream(somePath, FileMode.Create);
writer = new StreamWriter(fs);
writer.Write("Some Stuff");
/// put more useful stuff here
}
finally
{
if(writer!= null)
{
writer.Close();
}
if(fs!=null)
{
fs.Close();
}
}

No matter what happens in the code the stream will be closed as it is within the finally braces.
The error will no longer occur, additionally if you have the problem with one of your files in windows if you log out and log back in it will clear all the filestreams.

Your sample can be further simplified to:
Code:
TextWriter file = File.Create(somePath);
try
{
	file.WriteLine("Some Stuff");
	file.Flush();
}
finally
{
	file.Close();
}

There is no need to declare file as null outside of the try{} block and then instantiate it inside the try{} block because if File.Create fails/throws an exception, there will be no stream for the caller to close so I instantiate it outside of the try{} block because file would have to be a valid instance of a TextWriter to enter the try{} block.

Its usually good practice to call flush before close but in this case, flush is called by the StreamReader when Close() is called, so in my example, the call to flush is redundant and can removed.

Creating a StreamWriter by passing an instance of a FileStream and then calling Close on both the FIleStream and StreamWriter is also redundant as the StreamWriter class already does this for you.

Minor things, but it produces slightly more effecient, but more importantly, more readable code.
 
or if you want to get even more compact ;)
C#:
using(TextWriter file = File.Create(somePath))
{
file.WriteLine("Some Stuff");
file.Flush();
}

and even the Flush is probably un-needed.
 
Back
Top