Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top