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


Как прочитать встроенный ресурс (текстовый файл) с помощью 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();
}
15 544

15 ответов:

можно использовать 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 метод.

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

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

метод 1: добавьте существующий файл, установите свойство в Embedded Resource

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

Примечание: Если вы добавляете файл с помощью этого метода, вы можете использовать GetManifestResourceStream чтобы получить к нему доступ (см. ответ от @ЦЭТВ).

enter image description here

Способ 2: Добавить файл в Resources.resx

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

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

enter image description here

взгляните на эту страницу: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!");
   }

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

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

byte[] clistAsByteArray = Properties.Resources.CLIST01;

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

на самом деле вы можете перейти на ресурсы.Дизайнер.CS и посмотреть, как называется геттер.

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

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

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

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

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

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

A "." in filename is no good.

Шаблоны.plainEmailBodyTemplate-ru.тхт --> работает!!!
Шаблоны.plainEmailBodyTemplate.эн.txt --> не работает через GetManifestResourceStream ()

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

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

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

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

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

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

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

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

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

С NETMF нет GetManifestResourceStream

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

использование:

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

}

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

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

читать встроенный файл txt на событии load формы.

установите переменные динамически.

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