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

当前回答

阅读了这里张贴的所有解决方案后。我就是这样解决的:

// 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 "";      
}

其他回答

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

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

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

您也可以使用@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();
    }
}

当您将文件添加到资源中时,您应该将其“访问修改器”选择为“公共”,然后再进行如下操作。

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01是嵌入文件的名称。

实际上,您可以访问resources.Designer.cs,查看getter的名称。

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");

我想将嵌入式资源作为字节数组读取(不考虑任何特定编码),最后我使用了MemoryStream,这使得它非常简单:

using var resStream = assembly.GetManifestResourceStream(GetType(), "file.txt");
var ms = new MemoryStream();
await resStream .CopyToAsync(ms);
var bytes = ms.ToArray();