How to read embedded resource text file

.NetEmbedded ResourceStreamreader

.Net Problem Overview


How do I read an embedded resource (text file) using StreamReader and return it as a string? My current script uses a Windows form and textbox that allows the user to find and replace text in a text file that is not embedded.

private void button1_Click(object sender, EventArgs e)
{
    StringCollection strValuesToSearch = new StringCollection();
    strValuesToSearch.Add("Apple");
    string stringToReplace;
    stringToReplace = textBox1.Text;

    StreamReader FileReader = new StreamReader(@"C:\MyFile.txt");
    string FileContents;
    FileContents = FileReader.ReadToEnd();
    FileReader.Close();
    foreach (string s in strValuesToSearch)
    {
        if (FileContents.Contains(s))
            FileContents = FileContents.Replace(s, stringToReplace);
    }
    StreamWriter FileWriter = new StreamWriter(@"MyFile.txt");
    FileWriter.Write(FileContents);
    FileWriter.Close();
}

.Net Solutions


Solution 1 - .Net

You can use the Assembly.GetManifestResourceStream Method:

  1. Add the following usings

     using System.IO;
     using System.Reflection;
    
  2. Set property of relevant file:
    Parameter Build Action with value Embedded Resource

  3. Use the following code

     var assembly = Assembly.GetExecutingAssembly();
     var resourceName = "MyCompany.MyProduct.MyFile.txt";
     
     using (Stream stream = assembly.GetManifestResourceStream(resourceName))
     using (StreamReader reader = new StreamReader(stream))
     {
         string result = reader.ReadToEnd();
     }
    

    resourceName is the name of one of the resources embedded in assembly. For example, if you embed a text file named "MyFile.txt" that is placed in the root of a project with default namespace "MyCompany.MyProduct", then resourceName is "MyCompany.MyProduct.MyFile.txt". You can get a list of all resources in an assembly using the Assembly.GetManifestResourceNames Method.


A no brainer astute to get the resourceName from the file name only (by pass the namespace stuff):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));

A complete example:

public string ReadResource(string name)
{
	// Determine path
	var assembly = Assembly.GetExecutingAssembly();
	string resourcePath = name;
	// Format: "{Namespace}.{Folder}.{filename}.{Extension}"
	if (!name.StartsWith(nameof(SignificantDrawerCompiler)))
	{
		resourcePath = assembly.GetManifestResourceNames()
			.Single(str => str.EndsWith(name));
	}

	using (Stream stream = assembly.GetManifestResourceStream(resourcePath))
	using (StreamReader reader = new StreamReader(stream))
	{
		return reader.ReadToEnd();
	}
}

Solution 2 - .Net

You can add a file as a resource using two separate methods.

The C# code required to access the file is different, depending on the method used to add the file in the first place.

Method 1: Add existing file, set property to Embedded Resource

Add the file to your project, then set the type to Embedded Resource.

NOTE: If you add the file using this method, you can use GetManifestResourceStream to access it (see answer from @dtb).

enter image description here

Method 2: Add file to Resources.resx

Open up the Resources.resx file, use the dropdown box to add the file, set Access Modifier to public.

NOTE: If you add the file using this method, you can use Properties.Resources to access it (see answer from @Night Walker).

enter image description here

Solution 3 - .Net

Basically, you use System.Reflection to get a reference to the current Assembly. Then, you use GetManifestResourceStream().

Example, from the page I posted:

Note: need to add using System.Reflection; for this to work

   Assembly _assembly;
   StreamReader _textStreamReader;

   try
   {
      _assembly = Assembly.GetExecutingAssembly();
      _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
   }
   catch
   {
      MessageBox.Show("Error accessing resources!");
   }

Solution 4 - .Net

In Visual Studio you can directly embed access to a file resource via the Resources tab of the Project properties ("Analytics" in this example). visual studio screen shot - Resources tab

The resulting file can then be accessed as a byte array by

byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;

Should you need it as a stream, then ( from https://stackoverflow.com/a/4736185/432976 )

Stream stream = new MemoryStream(jsonSecrets)

Solution 5 - .Net

When you added the file to the resources, you should select its Access Modifiers as public than you can make something like following.

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01 is the name of the embedded file.

Actually you can go to the resources.Designer.cs and see what is the name of the getter.

Solution 6 - .Net

adding e.g. Testfile.sql Project Menu -> Properties -> Resources -> Add Existing file

    string queryFromResourceFile = Properties.Resources.Testfile.ToString();

enter image description here

Solution 7 - .Net

I know it is an old thread, but this is what worked for me :

  1. add the text file to the project resources

  2. set the access modifier to public, as showed above by Andrew Hill

  3. read the text like this :

    textBox1 = new TextBox();
    textBox1.Text = Properties.Resources.SomeText;
    

The text that I added to the resources: 'SomeText.txt'

Solution 8 - .Net

Something I learned just now is that your file is not allowed to have a "." (dot) in the filename.

A

Templates.plainEmailBodyTemplate-en.txt --> Works!!!
Templates.plainEmailBodyTemplate.en.txt --> doesn't work via GetManifestResourceStream()

Probably because the framework gets confused over namespaces vs filename...

Solution 9 - .Net

You can also use this simplified version of @dtb's answer:

public string GetEmbeddedResource(string ns, string res)
{
    using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", ns, res))))
    {
        return reader.ReadToEnd();
    }
}

Solution 10 - .Net

By all your powers combined I use this helper class for reading resources from any assembly and any namespace in a generic way.

public class ResourceReader
{
    public static IEnumerable<string> FindEmbededResources<TAssembly>(Func<string, bool> predicate)
    {
        if (predicate == null) throw new ArgumentNullException(nameof(predicate));

        return
            GetEmbededResourceNames<TAssembly>()
                .Where(predicate)
                .Select(name => ReadEmbededResource(typeof(TAssembly), name))
                .Where(x => !string.IsNullOrEmpty(x));
    }

    public static IEnumerable<string> GetEmbededResourceNames<TAssembly>()
    {
        var assembly = Assembly.GetAssembly(typeof(TAssembly));
        return assembly.GetManifestResourceNames();
    }

    public static string ReadEmbededResource<TAssembly, TNamespace>(string name)
    {
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
        return ReadEmbededResource(typeof(TAssembly), typeof(TNamespace), name);
    }

    public static string ReadEmbededResource(Type assemblyType, Type namespaceType, string name)
    {
        if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
        if (namespaceType == null) throw new ArgumentNullException(nameof(namespaceType));
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));

        return ReadEmbededResource(assemblyType, $"{namespaceType.Namespace}.{name}");
    }

    public static string ReadEmbededResource(Type assemblyType, string name)
    {
        if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));

        var assembly = Assembly.GetAssembly(assemblyType);
        using (var resourceStream = assembly.GetManifestResourceStream(name))
        {
            if (resourceStream == null) return null;
            using (var streamReader = new StreamReader(resourceStream))
            {
                return streamReader.ReadToEnd();
            }
        }
    }
}

Solution 11 - .Net

I know this is old, but I just wanted to point out for NETMF (.Net MicroFramework), you can easily do this:

string response = Resources.GetString(Resources.StringResources.MyFileName);

Since NETMF doesn't have GetManifestResourceStream

Solution 12 - .Net

I read an embedded resource text file use:

    /// <summary>
    /// Converts to generic list a byte array
    /// </summary>
    /// <param name="content">byte array (embedded resource)</param>
    /// <returns>generic list of strings</returns>
    private List<string> GetLines(byte[] content)
    {
        string s = Encoding.Default.GetString(content, 0, content.Length - 1);
        return new List<string>(s.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
    }

Sample:

var template = GetLines(Properties.Resources.LasTemplate /* resource name */);

template.ForEach(ln =>
{
    Debug.WriteLine(ln);
});

Solution 13 - .Net

Some VS .NET project types don’t auto-generate a .NET (.resx) file. The following steps add a Resource file to your project:

  1. Right-click the project node and select Add/New Item, scroll to Resources File. In the Name box choose an appropriate name, for instance Resources and click the button Add.
  2. The resource file Resources.resx is added to the project and can be seen as a node in the solution explorer.
  3. Actually, two files are created, there is also an auto-generated C# class Resources.Designer.cs. Don’t edit it, it is maintained by VS. The file contains a class named Resources.

Now you can add a text file as a resource, for example an xml file:

  1. Double-click Resources.resx. Select Add Resource > Add Existing File and scroll to the file you want to be included. Leave the default value Internal for Access Modify.
  2. An icon represents the new resource item. If selected, the property pane shows its properties. For xml files, under the property Encoding select Unicode (UTF-8) – Codepage 65001 instead of the default local codepage. For other text files select the correct encoding of this file, for example codepage 1252.
  3. For text files like xml files, the class Resources has a property of type string that is named after the included file. If the file name is e.g. RibbonManifest.xml, then the property should have the name RibbonManifest. You find the exact name in the code file Resources.Designer.cs.
  4. Use the string property like any other string property, for example: string xml = Resources.RibbonManifest. The general form is ResourceFileName.IncludedTextFileName. Don’t use ResourceManager.GetString since the get-function of the string property has done that already.

Solution 14 - .Net

This is a class which you might find very convenient for reading embedded resource files from the current Assembly:

using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;

public static class EmbeddedResourceUtils
{
	public static string ReadFromResourceFile(string endingFileName)
	{
		var assembly = Assembly.GetExecutingAssembly();
		var manifestResourceNames = assembly.GetManifestResourceNames();

		foreach (var resourceName in manifestResourceNames)
		{
			var fileNameFromResourceName = _GetFileNameFromResourceName(resourceName);
			if (!fileNameFromResourceName.EndsWith(endingFileName))
			{
				continue;
			}

			using (var manifestResourceStream = assembly.GetManifestResourceStream(resourceName))
			{
				if (manifestResourceStream == null)
				{
					continue;
				}

				using (var streamReader = new StreamReader(manifestResourceStream))
				{
					return streamReader.ReadToEnd();
				}
			}
		}

		return null;
	}
	
	// https://stackoverflow.com/a/32176198/3764804
	private static string _GetFileNameFromResourceName(string resourceName)
	{
		var stringBuilder = new StringBuilder();
		var escapeDot = false;
		var haveExtension = false;

		for (var resourceNameIndex = resourceName.Length - 1;
			resourceNameIndex >= 0;
			resourceNameIndex--)
		{
			if (resourceName[resourceNameIndex] == '_')
			{
				escapeDot = true;
				continue;
			}

			if (resourceName[resourceNameIndex] == '.')
			{
				if (!escapeDot)
				{
					if (haveExtension)
					{
						stringBuilder.Append('\\');
						continue;
					}

					haveExtension = true;
				}
			}
			else
			{
				escapeDot = false;
			}

			stringBuilder.Append(resourceName[resourceNameIndex]);
		}

		var fileName = Path.GetDirectoryName(stringBuilder.ToString());
		return fileName == null ? null : new string(fileName.Reverse().ToArray());
	}
}

Solution 15 - .Net

After reading all the solutions posted here. This is how I solved it:

// How to embedded a "Text file" inside of a C# project
//   and read it as a resource from c# code:
//
// (1) Add Text File to Project.  example: 'myfile.txt'
//
// (2) Change Text File Properties:
//      Build-action: EmbeddedResource
//      Logical-name: myfile.txt      
//          (note only 1 dot permitted in filename)
//
// (3) from c# get the string for the entire embedded file as follows:
//
//     string myfile = GetEmbeddedResourceFile("myfile.txt");

public static string GetEmbeddedResourceFile(string filename) {
	var a = System.Reflection.Assembly.GetExecutingAssembly();
	using (var s = a.GetManifestResourceStream(filename))
	using (var r = new System.IO.StreamReader(s))
	{
		string result = r.ReadToEnd();
		return result;
	}
	return "";		
}

Solution 16 - .Net

The answer is quite simple, simply do this if you added the file directly from the resources.resx.

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

With that line of code, the text from the file is directly read from the file and put into the string variable.

Solution 17 - .Net

public class AssemblyTextFileReader
{
	private readonly Assembly _assembly;

	public AssemblyTextFileReader(Assembly assembly)
	{
		_assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
	}

	public async Task<string> ReadFileAsync(string fileName)
	{
		var resourceName = _assembly.GetManifestResourceName(fileName);

		using (var stream = _assembly.GetManifestResourceStream(resourceName))
		{
			using (var reader = new StreamReader(stream))
			{
				return await reader.ReadToEndAsync();
			}
		}
	}
}

public static class AssemblyExtensions
{
	public static string GetManifestResourceName(this Assembly assembly, string fileName)
	{
		string name = assembly.GetManifestResourceNames().SingleOrDefault(n => n.EndsWith(fileName, StringComparison.InvariantCultureIgnoreCase));

		if (string.IsNullOrEmpty(name))
		{
			throw new FileNotFoundException($"Embedded file '{fileName}' could not be found in assembly '{assembly.FullName}'.", fileName);
		}

		return name;
	}
}
// To use the code above:
var reader = new AssemblyTextFileReader(assembly);

string text = await reader.ReadFileAsync(@"MyFile.txt");

Solution 18 - .Net

I wanted to read the embedded resource just as a byte array (without assuming any specific encoding), and I ended up using a MemoryStream which makes it very simple:

using var resStream = assembly.GetManifestResourceStream(GetType(), "file.txt");
var ms = new MemoryStream();
await resStream .CopyToAsync(ms);
var bytes = ms.ToArray();

Solution 19 - .Net

I was annoyed that you had to always include the namespace and the folder in the string. I wanted to simplify the access to the embedded resources. This is why I wrote this little class. Feel free to use and improve!

Usage:

using(Stream stream = EmbeddedResources.ExecutingResources.GetStream("filename.txt"))
{
 //...
}

Class:

public class EmbeddedResources
{
    private static readonly Lazy<EmbeddedResources> _callingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetCallingAssembly()));

    private static readonly Lazy<EmbeddedResources> _entryResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetEntryAssembly()));

    private static readonly Lazy<EmbeddedResources> _executingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetExecutingAssembly()));

    private readonly Assembly _assembly;

    private readonly string[] _resources;

    public EmbeddedResources(Assembly assembly)
    {
        _assembly = assembly;
        _resources = assembly.GetManifestResourceNames();
    }

    public static EmbeddedResources CallingResources => _callingResources.Value;

    public static EmbeddedResources EntryResources => _entryResources.Value;

    public static EmbeddedResources ExecutingResources => _executingResources.Value;

    public Stream GetStream(string resName) => _assembly.GetManifestResourceStream(_resources.Single(s => s.Contains(resName)));

}

Solution 20 - .Net

As indicated by SonarCloud better to do:

public class Example
{
    public static void Main()
    { 
        // Compliant: type of the current class
        Assembly assembly = typeof(Example).Assembly; 
        Console.WriteLine("Assembly name: {0}", assem.FullName);

        // Non-compliant
        Assembly assembly = Assembly.GetExecutingAssembly();
        Console.WriteLine("Assembly name: {0}", assem.FullName);
    }
}

Solution 21 - .Net

For all the people that just quickly want the text of a hardcoded file in winforms;

  1. Right-click your application in the solution explorer > Resources > Add your file.
  2. Click on it, and in the properties tab set the "FileType" to "Text".
  3. In your program just do Resources.<name of resource>.toString(); to read the file.

I would not recommend this as best practice or anything, but it works quickly and does what it needs to do.

Solution 22 - .Net

Read Embedded TXT FILE on Form Load Event.

###Set the Variables Dynamically.

string f1 = "AppName.File1.Ext";
string f2 = "AppName.File2.Ext";
string f3 = "AppName.File3.Ext";
Call a Try Catch.
try 
{
     IncludeText(f1,f2,f3); 
     /// Pass the Resources Dynamically 
     /// through the call stack.
}

catch (Exception Ex)
{
     MessageBox.Show(Ex.Message);  
     /// Error for if the Stream is Null.
}

###Create Void for IncludeText(), Visual Studio Does this for you. Click the Lightbulb to AutoGenerate The CodeBlock.

Put the following inside the Generated Code Block

##Resource 1

var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file1))
using (StreamReader reader = new StreamReader(stream))
{
string result1 = reader.ReadToEnd();
richTextBox1.AppendText(result1 + Environment.NewLine + Environment.NewLine );
}

##Resource 2

var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file2))
using (StreamReader reader = new StreamReader(stream))
{
string result2 = reader.ReadToEnd();
richTextBox1.AppendText(
result2 + Environment.NewLine + 
Environment.NewLine );
}

##Resource 3

var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file3))

using (StreamReader reader = new StreamReader(stream))
{
    string result3 = reader.ReadToEnd();
    richTextBox1.AppendText(result3);
}

###If you wish to send the returned variable somewhere else, just call another function and...

using (StreamReader reader = new StreamReader(stream))
{
    string result3 = reader.ReadToEnd();
    ///richTextBox1.AppendText(result3);
    string extVar = result3;
    
    /// another try catch here.

   try {
   
   SendVariableToLocation(extVar)
   {
         //// Put Code Here.
   }

       }

  catch (Exception ex)
  {
    Messagebox.Show(ex.Message);
  }

}

What this achieved was this, a method to combine multiple txt files, and read their embedded data, inside a single rich text box. which was my desired effect with this sample of Code.

Solution 23 - .Net

For users that are using VB.Net

Imports System.IO
Imports System.Reflection

Dim reader As StreamReader
Dim ass As Assembly = Assembly.GetExecutingAssembly()
Dim sFileName = "MyApplicationName.JavaScript.js" 
Dim reader = New StreamReader(ass.GetManifestResourceStream(sFileName))
Dim sScriptText = reader.ReadToEnd()
reader.Close()

where MyApplicationName is namespace of my application. It is not the assembly name. This name is define in project's properties (Application tab).

If you don't find correct resource name, you can use GetManifestResourceNames() function

Dim resourceName() As String = ass.GetManifestResourceNames()

or

Dim sName As String 
    = ass.GetManifestResourceNames()
        .Single(Function(x) x.EndsWith("JavaScript.js"))

or

Dim sNameList 
    = ass.GetManifestResourceNames()
        .Where(Function(x As String) x.EndsWith(".js"))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMe.CloseView Question on Stackoverflow
Solution 1 - .NetdtbView Answer on Stackoverflow
Solution 2 - .NetContangoView Answer on Stackoverflow
Solution 3 - .NetChris LaplanteView Answer on Stackoverflow
Solution 4 - .NetAndrew HillView Answer on Stackoverflow
Solution 5 - .NetNight WalkerView Answer on Stackoverflow
Solution 6 - .Netmiciry89View Answer on Stackoverflow
Solution 7 - .NetS_TeoView Answer on Stackoverflow
Solution 8 - .NetPeter GfaderView Answer on Stackoverflow
Solution 9 - .NetTimmerzView Answer on Stackoverflow
Solution 10 - .Nett3chb0tView Answer on Stackoverflow
Solution 11 - .Netdreamwork801View Answer on Stackoverflow
Solution 12 - .NetSith2021View Answer on Stackoverflow
Solution 13 - .NetDietrich BaumgartenView Answer on Stackoverflow
Solution 14 - .NetBullyWiiPlazaView Answer on Stackoverflow
Solution 15 - .NetBimoView Answer on Stackoverflow
Solution 16 - .NetJamiscoView Answer on Stackoverflow
Solution 17 - .NetbytedevView Answer on Stackoverflow
Solution 18 - .NetSaeb AminiView Answer on Stackoverflow
Solution 19 - .NetFelix KeilView Answer on Stackoverflow
Solution 20 - .NetMatteo GariglioView Answer on Stackoverflow
Solution 21 - .NetSwatView Answer on Stackoverflow
Solution 22 - .NetMasterCassidyView Answer on Stackoverflow
Solution 23 - .NetschlebeView Answer on Stackoverflow