Как читать встроенный текстовый файл ресурсов

Как прочитать встроенный ресурс (текстовый файл) с помощью StreamReader и вернуть его как строку? В моем текущем script используется форма и текстовое поле 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();
}
+636
источник поделиться
18 ответов

Вы можете использовать метод 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"));
+1109
источник

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

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

Способ 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

+126
источник
другие ответы

Связанные вопросы


Похожие вопросы

По сути, вы используете 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!");
   }
+84
источник

В Visual Studio вы можете напрямую встраивать доступ к файловому ресурсу через вкладку "Ресурсы" свойств проекта ( "Аналитика" в этом примере). visual studio screen shot - Resources tab

После этого результирующий файл можно получить в виде байтового массива с помощью

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

Если вам нужно это как поток, то (из qaru.site/questions/15054/...)

Stream stream = new MemoryStream(jsonSecrets)
+68
источник

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

byte[] clistAsByteArray = Properties.Resources.CLIST01;

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

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

+27
источник

Я знаю, что это старый поток, но это то, что сработало для меня:

  • добавить текстовый файл в ресурсы проекта
  • установите общедоступный модификатор доступа, как показано выше Andrew Hill
  • прочитайте текст следующим образом:

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

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

+12
источник

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

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

enter image description here

+12
источник

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

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

A "." in filename is no good.

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

Возможно, из-за того, что структура запуталась в пространствах имен vs filename...

+7
источник

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

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();
            }
        }
    }
}
+6
источник

Я прочитал использование встроенного текстового файла ресурсов:

    /// <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);
});
+4
источник

Я знаю, что это старый, но я просто хотел указать на NETMF (.Net MicroFramework), вы можете легко сделать это:

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

Так как NETMF не имеет GetManifestResourceStream

+3
источник

Прочитав все решения, размещенные здесь. Вот как я это решил:

// 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 "";      
}
+3
источник

Меня раздражало, что вы должны всегда включать пространство имен и папку в строке. Я хотел упростить доступ к встроенным ресурсам. Вот почему я написал этот маленький класс. Не стесняйтесь использовать и улучшать!

Применение:

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

}
+2
источник

Ответ довольно прост, просто сделайте это, если вы добавили файл непосредственно из resources.resx.

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

С этой строкой кода текст из файла непосредственно читается из файла и помещается в строковую переменную.

+2
источник
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;
    }
}
+1
источник

Некоторые типы проектов VS.NET не генерируют файл .NET(.resx) автоматически. Следующие шаги добавляют файл ресурсов в ваш проект:

  1. Щелкните правой кнопкой мыши узел проекта и выберите Добавить/Новый элемент, выделите Файл ресурсов. В поле "Имя" выберите подходящее имя, например "Ресурсы", и нажмите кнопку "Добавить".
  2. Файл ресурсов Resources.resx добавляется в проект и может рассматриваться как узел в обозревателе решений.
  3. На самом деле, два файла созданы, есть также автоматически сгенерированный С# класс Resources.Designer.cs. Не редактируйте его, он поддерживается VS. Файл содержит класс с именем Resources.

Теперь вы можете добавить текстовый файл в качестве ресурса, например, XML файл:

  1. Дважды щелкните Resources.resx. Выберите Добавить ресурс> Добавить существующий файл и выделите файл, который вы хотите включить. Оставьте значение по умолчанию Internal для Access Modify.
  2. Значок представляет новый элемент ресурса. Если этот параметр выбран, панель свойств отображает его свойства. Для файлов XML в свойстве Кодировка выберите Unicode (UTF-8) - Кодовая страница 65001 вместо локальной кодовой страницы по умолчанию. Для других текстовых файлов выберите правильную кодировку этого файла, например, кодовую страницу 1252.
  3. Для текстовых файлов, таких как XML файлы, класс Resources имеет свойство типа string, которое названо в честь включенного файла. Если имя файла, например, RibbonManifest.xml, тогда свойство должно иметь имя RibbonManifest. Точное имя вы найдете в файле кода Resources.Designer.cs.
  4. Используйте строковое свойство, как и любое другое строковое свойство, например: string xml = Resources.RibbonManifest. Общая форма ResourceFileName.IncludedTextFileName. Не используйте ResourceManager.GetString, так как функция get свойства string уже сделала это.
0
источник

Чтение встроенного 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.
}

Создать Void для IncludeText(), Visual Studio Делает это для вас. Нажмите "Лампочка" для автогенерации кода.

Поместите следующее внутри блока сгенерированного кода

Ресурс 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 и прочитать их встроенные данные внутри одного богатого текстового поля. который был моим желаемым эффектом с этим образцом кода.

-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос