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();
}
You can use the Assembly.GetManifestResourceStream
Method:
Add the following usings
using System.IO;
using System.Reflection;
Set property of relevant file:
Parameter Build Action
with value Embedded Resource
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();
}
}
or as an async extension method:
internal static class AssemblyExtensions
{
public static async Task<string> ReadResourceAsync(this Assembly assembly, string name)
{
// Determine path
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(stream);
return await reader.ReadToEndAsync();
}
}
// Usage
string resourceText = await Assembly.GetExecutingAssembly().ReadResourceAsync("myResourceName");