.net 如何读取嵌入的资源文本文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3314140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:33:03  来源:igfitidea点击:

How to read embedded resource text file

.netembedded-resourcestreamreader

提问by Me.Close

How do I read an embedded resource (text file) using StreamReaderand return it as a string? My current script uses a Windows form and textbox that allows the user to find and replace text in a text file that is not embedded.

如何读取嵌入的资源(文本文件)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();
}

回答by dtb

You can use the Assembly.GetManifestResourceStreamMethod:

您可以使用该Assembly.GetManifestResourceStream方法

  1. Add the following usings

    using System.IO;
    using System.Reflection;
    
  2. Set property of relevant file:
    Parameter Build Actionwith value Embedded Resource

  3. Use the following code

  1. 添加以下用途

    using System.IO;
    using System.Reflection;
    
  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();
}

resourceNameis the name of one of the resources embedded in assembly. For example, if you embed a text file named "MyFile.txt"that is placed in the root of a project with default namespace "MyCompany.MyProduct", then resourceNameis "MyCompany.MyProduct.MyFile.txt". You can get a list of all resources in an assembly using the Assembly.GetManifestResourceNamesMethod.

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



A no brainer astute to get the resourceNamefrom the file name only (by pass the namespace stuff):

resourceName仅从文件名中获取 的明智之举(绕过命名空间内容):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));


A complete example:

一个完整的例子:

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

回答by Contango

You can add a file as a resource using two separate methods.

您可以使用两种不同的方法将文件添加为资源。

The C# code required to access the file is different, depending on the method used to add the file in the first place.

访问文件所需的 C# 代码是不同的,这取决于最初用于添加文件的方法。

Method 1: Add existing file, set property to Embedded Resource

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

Add the file to your project, then set the type to Embedded Resource.

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

NOTE: If you add the file using this method, you can use GetManifestResourceStreamto access it (see answer from @dtb).

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

enter image description here

在此处输入图片说明

Method 2: Add file to Resources.resx

方法二:添加文件 Resources.resx

Open up the Resources.resxfile, use the dropdown box to add the file, set Access Modifierto public.

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

NOTE: If you add the file using this method, you can use Properties.Resourcesto access it (see answer from @Night Walker).

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

enter image description here

在此处输入图片说明

回答by Chris Laplante

Basically, you use System.Reflectionto get a reference to the current Assembly. Then, you use GetManifestResourceStream().

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

Example, from the page I posted:

例如,从我发布的页面:

Note: need to add using System.Reflection;for this to work

注意:需要添加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!");
   }

回答by Andrew Hill

In Visual Studio you can directly embed access to a file resource via the Resources tab of the Project properties ("Analytics" in this example). visual studio screen shot - Resources tab

在 Visual Studio 中,您可以通过项目属性(在本例中为“分析”)的资源选项卡直接嵌入对文件资源的访问。 Visual Studio 屏幕截图 - 资源选项卡

The resulting file can then be accessed as a byte array by

然后可以通过以下方式将生成的文件作为字节数组访问

byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;

Should you need it as a stream, then ( from https://stackoverflow.com/a/4736185/432976)

如果您需要它作为流,那么(来自https://stackoverflow.com/a/4736185/432976

Stream stream = new MemoryStream(jsonSecrets)

回答by Night Walker

When you added the file to the resources, you should select its Access Modifiers as public than you can make something like following.

当您将文件添加到资源中时,您应该将其访问修饰符选择为公开,然后您可以进行如下操作。

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01 is the name of the embedded file.

CLIST01 是嵌入文件的名称。

Actually you can go to the resources.Designer.cs and see what is the name of the getter.

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

回答by miciry89

adding e.g. Testfile.sql Project Menu -> Properties -> Resources -> Add Existing file

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

    string queryFromResourceFile = Properties.Resources.Testfile.ToString();

enter image description here

在此处输入图片说明

回答by S_Teo

I know it is an old thread, but this is what worked for me :

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

  1. add the text file to the project resources
  2. set the access modifier to public, as showed above by Andrew Hill
  3. read the text like this :

    textBox1 = new TextBox();
    textBox1.Text = Properties.Resources.SomeText;
    
  1. 将文本文件添加到项目资源中
  2. 将访问修饰符设置为 public,如 Andrew Hill 所示
  3. 像这样阅读文本:

    textBox1 = new TextBox();
    textBox1.Text = Properties.Resources.SomeText;
    

The text that I added to the resources: 'SomeText.txt'

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

回答by t3chb0t

By all your powers combined I use this helper class for reading resources from any assembly and any namespace in a generic way.

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

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

回答by Timmerz

You can also use this simplified version of @dtb's answer:

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

回答by Peter Gfader

Something I learned just now is that your file is not allowed to have a "." (dot) in the filename.

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

A "." in filename is no good.

一种 ”。”  在文件名中是不好的。

Templates.plainEmailBodyTemplate-en.txt --> Works!!!
Templates.plainEmailBodyTemplate.en.txt --> doesn't work via GetManifestResourceStream()

Templates.plainEmailBodyTemplate-en.txt --> 有效!!!
Templates.plainEmailBodyTemplate.en.txt --> 通过 GetManifestResourceStream() 不起作用

Probably because the framework gets confused over namespaces vs filename...

可能是因为框架对命名空间与文件名感到困惑......