如何读取嵌入式资源文本文件

Me.*_*ose 643 .net streamreader embedded-resource

如何使用嵌入式资源(文本文件)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();
}
Run Code Online (Sandbox Code Playgroud)

dtb*_*dtb 1126

您可以使用Assembly.GetManifestResourceStream方法:

  1. 添加以下用法

    using System.IO;
    using System.Reflection;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 设置相关文件的属性:带有值的
    参数Build ActionEmbedded Resource

  3. 使用以下代码

var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyCompany.MyProduct.MyFile.txt";

using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
    string result = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)

resourceName是嵌入的资源之一的名称assembly.例如,如果您嵌入了一个名为的文本文件"MyFile.txt",该文件位于具有默认命名空间的项目的根目录中"MyCompany.MyProduct",那么resourceName就是"MyCompany.MyProduct.MyFile.txt".您可以使用Assembly.GetManifestResourceNamesMethod获取程序集中所有资源的列表.


没有必要resourceName从文件名中获取(通过传递名称空间的东西):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));
Run Code Online (Sandbox Code Playgroud)

  • 如果您的资源不是直接在项目根目录中,而是在某个子文件夹中,请不要忘记将此文件夹名称也放在resourceName中(例如"MyProjectNameSpace.MyProjectSubFolder.FileName.FileExtention") (59认同)
  • 值得一提的是,资源"Build Action"必须设置为"Embedded Resource" (18认同)
  • `GetManifestResourceStream`的参数需要@adrian指示的路径.如果它对任何人有帮助,那条路径就像@SimpleCoder在示例中所示:`MyNamespace.Filename.Ext`.我之前尝试过`MyNamespace.Resources.Filename.Ext`,但结果为null. (15认同)
  • 呃...`SignificantDrawerCompiler`? (7认同)
  • @ Me.Close:看一下[`Environment.SpecialFolder`](http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx)获取桌面文件夹.您需要记住,资源将根据其在项目中的路径进行命名空间,因此其名称可能不仅仅是`file1.txt`. (5认同)
  • 还对 SignificantDrawerCompiler 是什么感到困惑? (5认同)
  • 这里没有涉及的一个重点.如果您将文件另存为替代编码类型以处理奇数字符(在我的情况下为UTF8),则在读取流时可能会返回一个空文件.通过在流阅读器的构造函数中指定编码类型来解决此问题:`using(StreamReader reader = new StreamReader(stream,Encoding.UTF8))` (4认同)
  • 我是在 dll(不是可执行文件)中完成的,并且流始终为空。我是否必须使用带有显式类型的签名? (2认同)
  • 为了获取程序集名称前缀,我使用:Assembly.GetExecutingAssembly().GetName().Name.ToString() (2认同)
  • [GetManifestResourceStream](https://learn.microsoft.com/de-de/dotnet/api/system.reflection. assembly.getmanifestresourcestream?view=net-5.0#System_Reflection_Assembly_GetManifestResourceStream_System_Type_System_String_) 现在有一个重载,允许传递类型。所以命名空间的规范不再是必要的。这允许删除“GetManifestResourceNames”查找。请参阅[Saeb Amini]的回答(/sf/answers/4409205881/) (2认同)

Con*_*ngo 130

您可以使用两个单独的方法将文件添加为资源.

访问文件所需的C#代码是不同的,具体取决于首先添加文件的方法.

方法1:添加现有文件,将属性设置为 Embedded Resource

将文件添加到项目中,然后将类型设置为Embedded Resource.

注意:如果使用此方法添加文件,则可以使用GetManifestResourceStream它来访问它(请参阅@dtb中的答案).

在此输入图像描述

方法2:添加文件到 Resources.resx

打开Resources.resx文件,使用下拉框添加文件,设置Access Modifierpublic.

注意:如果使用此方法添加文件,则可以使用Properties.Resources它来访问它(请参阅@Night Walker的答案).

在此输入图像描述

  • 第三种方法是将文件添加到项目中,然后将"复制到输出目录"设置为"True".在编译时,文件被复制到输出目录中,您可以使用常规方法读取文件.示例:在要显示图像的WPF应用程序中. (5认同)
  • @Maslow将构建操作设置为"Resource"会创建链接资源,而将构建操作设置为"Embedded Resource"会将资源编译到输出程序集中.术语"链接资源"是"在编译时将文件复制到输出目录"的一个奇特术语(然后您可以使用任何常规方法在运行时读取该文件).有关这两种类型之间差异的更多信息,请参阅https://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.90).aspx上的添加和编辑资源(Visual C#). (3认同)

Chr*_*nte 85

请查看此页面:http://support.microsoft.com/kb/319292

基本上,您System.Reflection用来获取当前程序集的引用.然后,你使用GetManifestResourceStream().

例如,从我发布的页面:

注意:需要为此添加using System.Reflection;才能工作

   Assembly _assembly;
   StreamReader _textStreamReader;

   try
   {
      _assembly = Assembly.GetExecutingAssembly();
      _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
   }
   catch
   {
      MessageBox.Show("Error accessing resources!");
   }
Run Code Online (Sandbox Code Playgroud)

  • `var auxList = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();`当你想要学习确切的资源名称时,这个方法非常有用.(摘自http://stackoverflow.com/questions/27757/how-can-i-discover-the-path-of-an-embedded-resource) (39认同)
  • +1用于包含`namespace`作为资源名称的一部分 (32认同)

And*_*ill 69

在Visual Studio中,您可以通过Project属性的Resources选项卡直接嵌入对文件资源的访问(本例中为"Analytics"). visual studio屏幕截图 - 资源选项卡

然后,生成的文件可以作为字节数组来访问

byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;
Run Code Online (Sandbox Code Playgroud)

如果您需要它作为流,那么(来自/sf/answers/331532981/)

Stream stream = new MemoryStream(jsonSecrets)
Run Code Online (Sandbox Code Playgroud)

  • 您也可以将它与文本文件一起使用,在这种情况下,您将拥有:string jsonSecrets = YourNameSpace.Properties.Resources.YourFileName; (11认同)

Nig*_*ker 27

将文件添加到资源时,应将其"访问修饰符"选择为公开,而不是像下面这样进行操作.

byte[] clistAsByteArray = Properties.Resources.CLIST01;
Run Code Online (Sandbox Code Playgroud)

CLIST01是嵌入文件的名称.

实际上你可以去resources.Designer.cs看看getter的名字是什么.

  • 你能解释一下吗?当我在解决方案资源管理器中右键单击 - >属性,然后将`Action`设置为`Incorporated ressource`时,我在属性面板中没有任何`Access Modifiers`字段.另外,我没有`Propersites.Resources`类,在编译代码时,我得到了一个`当前上下文中出现的'属性'错误. (5认同)
  • 这只有在你将文件嵌入`Resources.resx`时才有效,请参阅我关于将文件嵌入到项目中的不同方法的答案. (2认同)

mic*_*y89 13

添加例如Testfile.sql项目菜单 - >属性 - >资源 - >添加现有文件

    string queryFromResourceFile = Properties.Resources.Testfile.ToString();
Run Code Online (Sandbox Code Playgroud)

  • 它将返回byte [],对于文本文件,使用`Encoding.UTF8.GetString(Properties.Resources.Testfile)` (2认同)

小智 12

我知道这是一个旧线程,但这对我有用:

  1. 将文本文件添加到项目资源中
  2. 将访问修饰符设置为public,如Andrew Hill所示
  3. 阅读这样的文字:

    textBox1 = new TextBox();
    textBox1.Text = Properties.Resources.SomeText;
    
    Run Code Online (Sandbox Code Playgroud)

我添加到资源的文本:'SomeText.txt'


Tim*_*erz 8

你也可以使用这个简化版的@ 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();
    }
}
Run Code Online (Sandbox Code Playgroud)


t3c*_*b0t 8

通过您的全部力量,我使用此帮助程序类以通用方式从任何程序集和任何名称空间中读取资源。

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 船长星球加一:P (3认同)

Pet*_*der 7

我刚刚学到的一点是你的文件不允许有"." (点)在文件名中.

一个

Templates.plainEmailBodyTemplate-en.txt - > Works !!!
Templates.plainEmailBodyTemplate.en.txt - >不能通过GetManifestResourceStream()工作

可能是因为框架在名称空间与文件名之间混淆了......

  • 抱歉.这是错的.点工作.(至少它对我有用,NET4.5)我不知道为什么你有这个bug. (3认同)

dre*_*801 5

我知道这是旧的,但我只是想指出NETMF(.Net MicroFramework),你可以很容易地做到这一点:

string response = Resources.GetString(Resources.StringResources.MyFileName);
Run Code Online (Sandbox Code Playgroud)

由于NETMF没有GetManifestResourceStream


Die*_*ten 5

某些 VS .NET 项目类型不会自动生成 .NET (.resx) 文件。以下步骤将资源文件添加到您的项目中:

\n\n
    \n
  1. 右键单击项目节点并选择“添加/新项目”,滚动到“资源文件”。在“名称”框中选择适当的名称,例如“资源”,然后单击“添加”按钮。
  2. \n
  3. 资源文件 Resources.resx 已添加到项目中,并且可以视为解决方案资源管理器中的节点。
  4. \n
  5. 实际上,创建了两个文件,还有一个自动生成的 C# 类 Resources.Designer.cs。\xe2\x80\x99不要编辑它,它是由VS维护的。该文件包含一个名为Resources.
  6. \n
\n\n

现在您可以添加文本文件作为资源,例如 xml 文件:

\n\n
    \n
  1. 双击 Resources.resx。选择“添加资源”>“添加现有文件”,然后滚动到要包含的文件。保留“访问修改”的默认值“内部”。
  2. \n
  3. 图标代表新的资源项。如果选择,属性窗格将显示其属性。对于 xml 文件,在属性编码下选择 Unicode (UTF-8) \xe2\x80\x93 代码页 65001,而不是默认的本地代码页。对于其他文本文件,请选择该文件的正确编码,例如代码页 1252。
  4. \n
  5. 对于像 xml 文件这样的文本文件,该类Resources具有一个string以包含的文件命名的 type 属性。如果文件名为 RibbonManifest.xml,则该属性的名称应为RibbonManifest。您可以在代码文件 Resources.Designer.cs 中找到确切的名称。
  6. \n
  7. 像任何其他字符串属性一样使用字符串属性,例如:string xml = Resources.RibbonManifest。一般形式为ResourceFileName.IncludedTextFileName. 不要使用\xe2\x80\x99 ResourceManager.GetString,因为字符串属性的 get 函数已经做到了这一点。
  8. \n
\n