如何使用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();
}

当前回答

您也可以使用@dtb答案的简化版本:

public string GetEmbeddedResource(string ns, string res)
{
    using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", ns, res))))
    {
        return reader.ReadToEnd();
    }
}

其他回答

您也可以使用@dtb答案的简化版本:

public string GetEmbeddedResource(string ns, string res)
{
    using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", ns, res))))
    {
        return reader.ReadToEnd();
    }
}

答案很简单,如果直接从resources.resx添加文件,只需这样做。

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

使用这行代码,文件中的文本将直接从文件中读取并放入字符串变量中。

我刚才了解到,文件名中不允许有“.”(点)。

Templates.plainMailBodyTemplate-en.txt-->工作!!!Templates.plainMailBodyTemplate.en.txt-->无法通过GetManifestResourceStream()工作

可能是因为框架混淆了名称空间和文件名。。。

如SonarCloud所示,更好的做法是:

public class Example
{
    public static void Main()
    { 
        // Compliant: type of the current class
        Assembly assembly = typeof(Example).Assembly; 
        Console.WriteLine("Assembly name: {0}", assem.FullName);

        // Non-compliant
        Assembly assembly = Assembly.GetExecutingAssembly();
        Console.WriteLine("Assembly name: {0}", assem.FullName);
    }
}

可以使用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");