Click here to Skip to main content
Email Password   helpLost your password?

Introduction

As I have written before in a previous article, creating large string variables can be a dull but necessary part of coding. Whether it's a bit of JavaScript or HTML for a web page, some SQL to create a database table or just a long bit of text for a tool tip, large strings are needed.

In the previous article, the included utility used a text file as a source, and wrote a code snippet that created and populated a string variable for you to use in your own code. This article takes a different approach by embedding the text file in your assembly and extracting it when needed.

The main advantage to this approach is maintainability. Since the text is not cut up by concatenation or StringBuilder.Append statements, it's easy to read and edit.

Using the code

Setting up the text file can be accomplished in 3 easy steps:

  1. Add a text file to your solution.
  2. Right-click on the file in the Solution Explorer and select "properties" to display the Properties window for the file.
  3. Change the "Build Action" to "Embedded Resource".

Once this is done, your file will be embedded in the assembly the next time you compile. Its contents can be read back using the following GetFromResources method and used to populate your string variable to be used in your application.

The code consists of a small method to extract the resource file as a string. Using reflection, a reference to the current assembly is created. Then, with the manifest reader method GetManifestResourceStream, the text file is read and returned as a string. That's it!

internal string GetFromResources(string resourceName)
{  
   Assembly assem = this.GetType().Assembly;   
   using( Stream stream = assem.GetManifestResourceStream(resourceName) )   
   {
     try      
     { 
       using( StreamReader reader = new StreamReader(stream) )         
       {
         return reader.ReadToEnd();         
       }
     }     
     catch(Exception e)      
     {
       throw new Exception("Error retrieving from Resources. Tried '" 
                                + resourceName+"'\r\n"+e.ToString());      
     }
   }
}

Using the method to populate a string variable is accomplished in one line of code:

string quote = 
  new EmbeddedResourceTextReader().GetFromResources
  ("McKechney.EmbeddedResouceTextExample.Folder.Shakespeare.txt");

Key Points to Remember:

I want to stress the last key point again. Several times I have changed only the embedded resource file and run my application only to see the old text returned. This can be pretty frustrating, especially if the expected change is buried deep in your application. If you remember that you need to rebuild your application after an embedded resource change, you'll be a much happier programmer.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalvery helpful
shashankkadge
3:37 12 Mar '10  
thanks for sharing
GeneralMost Excellent
campinas
17:38 5 Feb '07  
Great tip, well explained, all info to the point, concise. Most excellent.Smile

sm

GeneralCool example! There is also an example in MSDN...
SecondNature
15:28 21 Dec '06  
http://support.microsoft.com/kb/319292
GeneralVery Good
kignatov
5:35 19 Apr '05  
Only one point.

"The resourceName must be the fully qualified name of the file: Default Namespace + folder name(s) + filename (with extension if applicable)." - it is a good idea to bold the word "Default" as most of the people would just read through it. It is very important to know that the current namespace could be anything different than the default one and if you use it here the application just won't find the embedded resources.
Generalusing tatement
Santiago Corredoira
2:54 26 Sep '04  
using( Stream stream = assem.GetManifestResourceStream( resourceName ) )
I am curious if there is a reason for the using statement in this particular case or is it just a programming habit?

Anyway, very useful, thanks! Smile
GeneralRe: using tatement
Judah Himango
12:36 29 Sep '04  
The using keyword used in this context signifies the use of an IDisposable object. Utilizing the using keyword automatically disposes the object in the using statment after the statement is complete. So basically

using(Stream stream = assem.GetManifestResourceStream( resourceName )) 
{
stream.DoSomething();
}
)

is equivalent to writing

Stream stream = assem.GetManifestResourceStream( resourceName );

try {
stream.DoSomething();
}
finally {
stream.Close(); // Close will call the Dispose method of the IDisposable Stream
}



Judah Himango
GeneralWhen the strings contain HTML...
Anonymous
20:29 3 Aug '04  
If I embed a string containing an HTML page in to my application...can anyone tell me the best way to deal with references to web page images from within the HTML string?   I'm displaying the HTML in a web browser control.   Previously I was simply pointing the browser control to the file; now that I've embedded the HTML as a string I'm unsure how to deal with image addressing.   The relative links <img src="../UI/Images/MyImage.jpg"> that worked before no longer work (although the rest of the HTML does).
GeneralVery Useful
Colin Angus Mackay
12:35 18 Jun '04  
I've used this technique for months now and it is most useful. Now, if only I'd thought of turning it in to an article first.....

Big Grin


"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar

The Second EuroCPian Event will be in Brussels on the 4th of September

Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
My Blog



Last Updated 16 Jun 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010