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

当前回答

对于使用VB.Net的用户

Imports System.IO
Imports System.Reflection

Dim reader As StreamReader
Dim ass As Assembly = Assembly.GetExecutingAssembly()
Dim sFileName = "MyApplicationName.JavaScript.js" 
Dim reader = New StreamReader(ass.GetManifestResourceStream(sFileName))
Dim sScriptText = reader.ReadToEnd()
reader.Close()

其中MyApplicationName是应用程序的命名空间。它不是程序集名称。此名称在项目的财产(应用程序选项卡)中定义。

如果找不到正确的资源名称,可以使用GetManifestResourceNames()函数

Dim resourceName() As String = ass.GetManifestResourceNames()

or

Dim sName As String 
    = ass.GetManifestResourceNames()
        .Single(Function(x) x.EndsWith("JavaScript.js"))

or

Dim sNameList 
    = ass.GetManifestResourceNames()
        .Where(Function(x As String) x.EndsWith(".js"))

其他回答

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

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

通过您的所有能力,我使用这个助手类以通用方式从任何程序集和任何命名空间读取资源。

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();
            }
        }
    }
}

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

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

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

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

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

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

某些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函数已经完成了这一操作。