1

I am new to coding and have been doing lots of tutorials recently to learn how to use C# in Visual Studio. I recently started working on a project of my own design. The project is to generate webpages for viewing photos. Part of this requires that I copy a file called main.css to the working directory as this file defines the style of the Webpage. The line of code that I use to write this file is executed by a button click and is as follows:

Assembly.GetExecutingAssembly().GetManifestResourceStream("ThumbsCreator.main.css").CopyTo(new FileStream(folderPath + "//main.css", FileMode.Create));

ThumbsCreator is the namespace name and folderpath is a string containing the path to the working directory. When I run this code the main.css file always turns up but often is blank/empty until I run another function in the program or close the program. This seems to be a little inconsistent on what happens but closing the application always results in the correct content turning up in the css file. The content of the file is just text. Can anybody suggest how I can ensure that the css file is written out immediately after executing the above line of code?

1 Answer 1

1

You never close the file. That's why it's still open until you close the application (or until the garbage collector collects the FileStream instance). As long as it's open you cannot look into the file from other applications.

As a slightly longer answer: You open the file as soon as you create the FileStream instance. Since it cannot be referenced from anywhere else it will eventually be collected (in which case the finalizer will make sure that the file is closed). But this happens unpredictably at some point in time after creation, or not at all. Maybe. It depends on other allocations and whether the GC finds a good time to run.

Generally you should leave unmanaged resources (an open file is unmanaged because .NET doesn't know anything about it) open only as long as you need them. The easiest way in your case is the using statement:

using (var fs = File.Create(folderPath + "//main.css"))
{
    var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("ThumbsCreator.main.css");
    resource.CopyTo(fs);
}

This will ensure that the file is closed as soon as you leave the block.

It is somewhat analogous to

var fs = File.Create(folderPath + "//main.css");
var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("ThumbsCreator.main.css");
resource.CopyTo(fs);
fs.Close();

(Note: Only barely, but should be close enough for your understanding.) The point here is that using makes it clear which resource you allocate (a FileStream) and when it will be released again (at the end of the block). For things like files, network connections and other things that have a Dispose method, you should really start using (pun not intended) it.

Sign up to request clarification or add additional context in comments.

3 Comments

I'd really appreciate if you could tell me the code that I require to close this off correctly?
That works great. Thanks. I see that the end of the using statement must end and close the file out. I did have an if statement before my original code but there is no else condition. I wonder if adding an else statement would achieve the same effect? Or if the using statement is necessary to achieve this?
You can just as well write the other code (or a try/finally which is what using actually is under the hood), but your question regarding the if statement doesn't make much sense. if just executes one block (or another, if there is an else part) depending on a condition. Whether you open or close a file in an if or else block is up to you but totally irrelevant here, I'd say. using is just a convenience feature that allows you to manage lifetime of unmanaged resources, such as open files. You can do it all on your own if you like, though (not recommended).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.