问题
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();
}
回答1:
You can use the Assembly.GetManifestResourceStream Method:
Add the following usings
using System.IO; using System.Reflection;
Set property of relevant file:
ParameterBuild Action
with valueEmbedded 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"));
回答2:
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).

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).

回答3:
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!");
}
回答4:
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)
回答5:
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.
回答6:
adding e.g. Testfile.sql Project Menu -> Properties -> Resources -> Add Existing file
string queryFromResourceFile = Properties.Resources.Testfile.ToString();
回答7:
I know it is an old thread, but this is what worked for me :
- add the text file to the project resources
- set the access modifier to public, as showed above by Andrew Hill
read the text like this :
textBox1 = new TextBox(); textBox1.Text = Properties.Resources.SomeText;
The text that I added to the resources: 'SomeText.txt'
回答8:
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();
}
}
回答9:
Something I learned just now is that your file is not allowed to have a "." (dot) in the filename.

Templates.plainEmailBodyTemplate-en.txt --> Works!!!
Templates.plainEmailBodyTemplate.en.txt --> doesn't work via GetManifestResourceStream()
Probably because the framework gets confused over namespaces vs filename...
回答10:
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();
}
}
}
}
回答11:
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);
});
回答12:
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
回答13:
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 "";
}
回答14:
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)));
}
回答15:
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.
回答16:
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;
}
}
回答17:
Some VS .NET project types don’t auto-generate a .NET (.resx) file. The following steps add a Resource file to your project:
- 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.
- The resource file Resources.resx is added to the project and can be seen as a node in the solution explorer.
- 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:
- 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.
- 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.
- For text files like xml files, the class
Resources
has a property of typestring
that is named after the included file. If the file name is e.g. RibbonManifest.xml, then the property should have the nameRibbonManifest
. You find the exact name in the code file Resources.Designer.cs. - Use the string property like any other string property, for example:
string xml = Resources.RibbonManifest
. The general form isResourceFileName.IncludedTextFileName
. Don’t useResourceManager.GetString
since the get-function of the string property has done that already.
回答18:
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.
来源:https://stackoverflow.com/questions/3314140/how-to-read-embedded-resource-text-file