首页 文章

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

提问于
浏览
558

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

16 回答

  • 66
    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;
        }
    }
    
  • 114

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

    string response = Resources.GetString(Resources.StringResources.MyFileName);
    

    由于 NETMF 没有 GetManifestResourceStream

  • 84

    你也可以使用这个简化版的@ 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();
        }
    }
    
  • 12

    在Visual Studio中,您可以通过Project属性的Resources选项卡直接嵌入对文件资源的访问(在此示例中为"Analytics") .
    visual studio screen shot - Resources tab

    然后可以将生成的文件作为字节数组进行访问

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

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

    Stream stream = new MemoryStream(jsonSecrets)
    
  • 4

    通过所有的功能组合,我使用这个帮助器类以通用方式从任何程序集和任何命名空间中读取资源 .

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

    阅读完这里发布的所有解决方案后 . 这就是我解决它的方式:

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

    我读了一个嵌入式资源文本文件使用:

    /// <summary>
        /// Converts to generic list a byte array
        /// </summary>
        /// <param name="content">byte array (embedded resource)</param>
        /// <returns>generic list of strings</returns>
        private List<string> GetLines(byte[] content)
        {
            string s = Encoding.Default.GetString(content, 0, content.Length - 1);
            return new List<string>(s.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
        }
    

    样品:

    var template = GetLines(Properties.Resources.LasTemplate /* resource name */);
    
    template.ForEach(ln =>
    {
        Debug.WriteLine(ln);
    });
    
  • 26

    我很生气,你必须始终在字符串中包含命名空间和文件夹 . 我想简化对嵌入式资源的访问 . 这就是我写这个小班的原因 . 随意使用和改进!

    用法:

    using(Stream stream = EmbeddedResources.ExecutingResources.GetStream("filename.txt"))
    {
     //...
    }
    

    类:

    public class EmbeddedResources
    {
        private static readonly Lazy<EmbeddedResources> _callingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetCallingAssembly()));
    
        private static readonly Lazy<EmbeddedResources> _entryResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetEntryAssembly()));
    
        private static readonly Lazy<EmbeddedResources> _executingResources = new Lazy<EmbeddedResources>(() => new EmbeddedResources(Assembly.GetExecutingAssembly()));
    
        private readonly Assembly _assembly;
    
        private readonly string[] _resources;
    
        public EmbeddedResources(Assembly assembly)
        {
            _assembly = assembly;
            _resources = assembly.GetManifestResourceNames();
        }
    
        public static EmbeddedResources CallingResources => _callingResources.Value;
    
        public static EmbeddedResources EntryResources => _entryResources.Value;
    
        public static EmbeddedResources ExecutingResources => _executingResources.Value;
    
        public Stream GetStream(string resName) => _assembly.GetManifestResourceStream(_resources.Single(s => s.Contains(resName)));
    
    }
    
  • 7

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

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

    在表格加载事件上读取嵌入的TXT文件 .

    动态设置变量 .

    string f1 = "AppName.File1.Ext";
    string f2 = "AppName.File2.Ext";
    string f3 = "AppName.File3.Ext";
    

    调用Try Catch .

    try 
    {
         IncludeText(f1,f2,f3); 
         /// Pass the Resources Dynamically 
         /// through the call stack.
    }
    
    catch (Exception Ex)
    {
         MessageBox.Show(Ex.Message);  
         /// Error for if the Stream is Null.
    }
    

    为IncludeText()创建Void,Visual Studio为您做到这一点 . 单击灯泡以自动生成CodeBlock .

    将以下内容放入生成的代码块中

    资源1

    var assembly = Assembly.GetExecutingAssembly();
    using (Stream stream = assembly.GetManifestResourceStream(file1))
    using (StreamReader reader = new StreamReader(stream))
    {
    string result1 = reader.ReadToEnd();
    richTextBox1.AppendText(result1 + Environment.NewLine + Environment.NewLine );
    }
    

    资源2

    var assembly = Assembly.GetExecutingAssembly();
    using (Stream stream = assembly.GetManifestResourceStream(file2))
    using (StreamReader reader = new StreamReader(stream))
    {
    string result2 = reader.ReadToEnd();
    richTextBox1.AppendText(
    result2 + Environment.NewLine + 
    Environment.NewLine );
    }
    

    资源3

    var assembly = Assembly.GetExecutingAssembly();
    using (Stream stream = assembly.GetManifestResourceStream(file3))
    
    using (StreamReader reader = new StreamReader(stream))
    {
        string result3 = reader.ReadToEnd();
        richTextBox1.AppendText(result3);
    }
    

    如果您希望将返回的变量发送到其他地方,只需调用另一个函数并...

    using (StreamReader reader = new StreamReader(stream))
    {
        string result3 = reader.ReadToEnd();
        ///richTextBox1.AppendText(result3);
        string extVar = result3;
    
        /// another try catch here.
    
       try {
    
       SendVariableToLocation(extVar)
       {
             //// Put Code Here.
       }
    
           }
    
      catch (Exception ex)
      {
        Messagebox.Show(ex.Message);
      }
    
    }
    

    这实现了这一点,一种在单个富文本框内组合多个txt文件并读取其嵌入数据的方法 . 这个代码示例是我期望的效果 .

  • 3

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

    A "." in filename is no good.

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

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

  • 0

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

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

    方法1:添加现有文件,将属性设置为嵌入式资源

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

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

    enter image description here

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

    打开 Resources.resx 文件,使用下拉框添加文件,将 Access Modifier 设置为 public .

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

    enter image description here

  • 8

    你可以使用Assembly.GetManifestResourceStream Method

    • 添加以下用法
    using System.IO;
    using System.Reflection;
    
    • 设置相关文件的属性:
      参数 Build Action ,其值为 Embedded Resource

    • 使用以下代码

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

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


    从文件名中获取 resourceName (通过传递命名空间的东西)是一个明智的选择:

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

    看看这个页面:http://support.microsoft.com/kb/319292

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

    例如,从我发布的页面:

    Note :需要添加 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!");
       }
    
  • 2

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

    byte[] clistAsByteArray = Properties.Resources.CLIST01;
    

    CLIST01是嵌入文件的名称 .

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

  • 4

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

    • 将文本文件添加到项目资源中

    • 将访问修饰符设置为public,如Andrew Hill所示

    • 读取这样的文字:

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

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

相关问题