如何使用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");
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");
我读取了一个嵌入式资源文本文件,使用:
/// <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);
});