Как читать встроенный ресурсный текстовый файл - PullRequest
609 голосов
/ 23 июля 2010

Как прочитать встроенный ресурс (текстовый файл), используя 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();
}

Ответы [ 17 ]

1052 голосов
/ 23 июля 2010

Вы можете использовать Assembly.GetManifestResourceStream Метод :

  1. Добавьте следующие значения

    using System.IO;
    using System.Reflection;
    
  2. Установить свойство соответствующего файла:
    Параметр Build Action со значением Embedded 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();
}

resourceName - это имя одного из ресурсов, встроенных в assembly. Например, если вы встраиваете текстовый файл с именем "MyFile.txt", который находится в корне проекта с пространством имен по умолчанию "MyCompany.MyProduct", тогда resourceName равен "MyCompany.MyProduct.MyFile.txt". Вы можете получить список всех ресурсов в сборке, используя метод Assembly.GetManifestResourceNames .


Нет ничего сложного в том, чтобы получить resourceName только из имени файла (путем передачи содержимого пространства имен):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));
122 голосов
/ 27 октября 2014

Вы можете добавить файл в качестве ресурса, используя два отдельных метода.

Код C #, необходимый для доступа к файлу, отличается , в зависимости от метода, используемого для добавления файла.

Способ 1: добавить существующий файл, установить для свойства значение Embedded Resource

Добавьте файл в свой проект, затем установите тип Embedded Resource.

ПРИМЕЧАНИЕ. Если вы добавляете файл с помощью этого метода, вы можете использовать GetManifestResourceStream для доступа к нему (см. ответ от @ dtb ).

enter image description here

Метод 2: Добавить файл в Resources.resx

Откройте файл Resources.resx, используйте раскрывающийся список для добавления файла, установите Access Modifier на public.

ПРИМЕЧАНИЕ. Если вы добавляете файл с помощью этого метода, вы можете использовать Properties.Resources для доступа к нему (см. ответ от @Night Walker ).

enter image description here

84 голосов
/ 23 июля 2010

Взгляните на эту страницу: 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!");
   }
68 голосов
/ 24 октября 2013

В Visual Studio вы можете напрямую встроить доступ к файловому ресурсу через вкладку Ресурсы в свойствах проекта (в данном примере «Аналитика»).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)
27 голосов
/ 20 апреля 2012

Когда вы добавили файл к ресурсам, вы должны выбрать его модификаторы доступа как общедоступные, после чего вы можете сделать что-то вроде следующего.

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01 - это имя встроенного файла.

На самом деле вы можете перейти к resources.Designer.cs и посмотреть, как называется получатель.

12 голосов
/ 30 декабря 2013

Я знаю, что это старая ветка, но вот что у меня сработало:

  1. добавить текстовый файл к ресурсам проекта
  2. установить модификатор доступа public, какпоказанный Эндрю Хиллом
  3. читать текст так:

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

Текст, который я добавил в ресурсы: 'SomeText.txt'

12 голосов
/ 14 марта 2017

добавление, например Testfile.sql Меню проекта -> Свойства -> Ресурсы -> Добавить существующий файл

    string queryFromResourceFile = Properties.Resources.Testfile.ToString();
8 голосов
/ 08 июля 2013

Вы также можете использовать эту упрощенную версию ответа @ 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();
    }
}
7 голосов
/ 03 июля 2015

То, что я только что узнал, - это то, что вашему файлу не разрешено иметь "." (точка) в имени файла.

A

Templates.plainEmailBodyTemplate-en.txt -> Работает !!!
Templates.plainEmailBodyTemplate.en.txt -> не работает через GetManifestResourceStream ()

Возможно, потому что инфраструктура запутывается в пространствах имен против имени файла ...

6 голосов
/ 11 февраля 2017

Всеми своими силами я использую этот вспомогательный класс для чтения ресурсов из любой сборки и любого пространства имен в общем виде.

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