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
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.
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).
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).
In Visual Studio you can directly embed access to a file resource via the Resources tab of the Project properties ("Analytics" in this example).
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)
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();
}
}
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!");
}
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.
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)));
}