如何使用StreamReader读取嵌入式资源(文本文件)并将其作为字符串返回?我当前的脚本使用Windows窗体和文本框,允许用户查找和替换未嵌入的文本文件中的文本。
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();
}
可以使用Assembly.GetManifestResourceStream方法:
添加以下用法使用System.IO;使用System.Reflection;设置相关文件的属性:具有值Embedded Resource的参数生成操作使用以下代码var assembly=assembly.GetExecutingAssembly();var resourceName=“MyCompany.MyProduct.MyFile.txt”;使用(流流=程序集.GetManifestResourceStream(resourceName))使用(StreamReader读取器=新StreamReader(流)){string result=reader.ReadToEnd();}resourceName是程序集中嵌入的资源之一的名称。例如,如果嵌入了一个名为“MyFile.txt”的文本文件,该文件位于默认名称为“MyCompany.MyProduct”的项目根目录中,则resourceName为“MyCompany.MyProduct.MyFile.txt”。可以使用assembly.GetManifestResourceNames方法获取程序集中所有资源的列表。
只从文件名中获取resourceName(通过传递名称空间)是一个非常明智的做法:
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("YourFileName.txt"));
完整示例:
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();
}
}
或作为异步扩展方法:
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");
某些VS.NET项目类型不会自动生成.NET(.resx)文件。以下步骤将资源文件添加到项目中:
右键单击项目节点并选择Add/NewItem,滚动到Resources File。在“名称”框中选择适当的名称,例如“资源”,然后单击“添加”按钮。资源文件Resources.resx被添加到项目中,并且可以作为解决方案资源管理器中的节点。实际上,创建了两个文件,还有一个自动生成的C#类Resources.Designer.cs。不要编辑它,它由VS维护。该文件包含一个名为Resources的类。
现在,您可以添加文本文件作为资源,例如xml文件:
双击Resources.resx。选择“添加资源”>“添加现有文件”,然后滚动到要包含的文件。将默认值“内部”保留为“访问修改”。图标表示新资源项。如果选中,属性窗格将显示其财产。对于xml文件,在属性Encoding下选择Unicode(UTF-8)–Codepage 65001,而不是默认的本地代码页。对于其他文本文件,请选择此文件的正确编码,例如代码页1252。对于像xml文件这样的文本文件,类Resources具有一个字符串类型的属性,该属性以包含的文件命名。如果文件名为例如RibbonManifest.xml,则属性的名称应为RibbonManifest。您可以在代码文件Resources.Designer.cs中找到确切的名称。像使用任何其他字符串属性一样使用字符串属性,例如:string xml=Resources.RibbonManifest。一般形式为ResourceFileName.IncludedTextFileName。不要使用ResourceManager.GetString,因为字符串属性的get函数已经完成了这一操作。
可以使用Assembly.GetManifestResourceStream方法:
添加以下用法使用System.IO;使用System.Reflection;设置相关文件的属性:具有值Embedded Resource的参数生成操作使用以下代码var assembly=assembly.GetExecutingAssembly();var resourceName=“MyCompany.MyProduct.MyFile.txt”;使用(流流=程序集.GetManifestResourceStream(resourceName))使用(StreamReader读取器=新StreamReader(流)){string result=reader.ReadToEnd();}resourceName是程序集中嵌入的资源之一的名称。例如,如果嵌入了一个名为“MyFile.txt”的文本文件,该文件位于默认名称为“MyCompany.MyProduct”的项目根目录中,则resourceName为“MyCompany.MyProduct.MyFile.txt”。可以使用assembly.GetManifestResourceNames方法获取程序集中所有资源的列表。
只从文件名中获取resourceName(通过传递名称空间)是一个非常明智的做法:
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("YourFileName.txt"));
完整示例:
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();
}
}
或作为异步扩展方法:
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");
我读取了一个嵌入式资源文本文件,使用:
/// <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));
}
示例:
var template = GetLines(Properties.Resources.LasTemplate /* resource name */);
template.ForEach(ln =>
{
Debug.WriteLine(ln);
});