Как читать встроенный текстовый файл ресурсов
Как прочитать встроенный ресурс (текстовый файл) с помощью 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();
}
Ответы
Ответ 1
Вы можете использовать метод Assembly.GetManifestResourceStream
:
-
Добавьте следующие слова
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();
}
resourceName
- это имя одного из ресурсов, встроенных в assembly
. Например, если вы встраиваете текстовый файл с именем "MyFile.txt"
который помещается в корень проекта с пространством имен по умолчанию "MyCompany.MyProduct"
, то resourceName
будет "MyCompany.MyProduct.MyFile.txt"
. Вы можете получить список всех ресурсов в сборке, используя метод Assembly.GetManifestResourceNames
.
Нетрудно догадаться, чтобы получить resourceName
из имени файла (путем передачи содержимого пространства имен):
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("YourFileName.txt"));
Ответ 2
Вы можете добавить файл в качестве ресурса, используя два отдельных метода.
Код С#, необходимый для доступа к файлу, отличается, в зависимости от метода, использованного для добавления файла.
Способ 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]()
Ответ 3
По сути, вы используете 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!");
}
Ответ 4
В Visual Studio вы можете напрямую встраивать доступ к файловому ресурсу через вкладку "Ресурсы" свойств проекта ( "Аналитика" в этом примере).
![visual studio screen shot - Resources tab]()
После этого результирующий файл можно получить в виде байтового массива с помощью
byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;
Если вам нужно это как поток, то (из fooobar.com/questions/15054/...)
Stream stream = new MemoryStream(jsonSecrets)
Ответ 5
Когда вы добавили файл в ресурсы, вы должны выбрать его модификаторы доступа как общедоступные, чем вы можете сделать следующее.
byte[] clistAsByteArray = Properties.Resources.CLIST01;
CLIST01 - это имя встроенного файла.
На самом деле вы можете перейти к resources.Designer.cs и посмотреть, что такое имя получателя.
Ответ 6
Я знаю, что это старый поток, но это то, что сработало для меня:
Текст, который я добавил в ресурсы: 'SomeText.txt'
Ответ 7
добавив, например, Testfile.sql Меню проекта → Свойства → Ресурсы → Добавить существующий файл
string queryFromResourceFile = Properties.Resources.Testfile.ToString();
![enter image description here]()
Ответ 8
Вы также можете использовать эту упрощенную версию ответа @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();
}
}
Ответ 9
Что-то, что я узнал сейчас, это то, что вашему файлу не разрешено иметь ".". (точка) в имени файла.
![A "." in filename is no good.]()
Templates.plainEmailBodyTemplate-en.txt → Работает!!!
Templates.plainEmailBodyTemplate.en.txt → не работает через GetManifestResourceStream()
Возможно, из-за того, что структура запуталась в пространствах имен vs filename...
Ответ 10
Со всеми вашими полномочиями я использую этот вспомогательный класс для чтения ресурсов из любой сборки и любого пространства имен общим способом.
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();
}
}
}
}
Ответ 11
Я прочитал использование встроенного текстового файла ресурсов:
/// <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);
});
Ответ 12
Я знаю, что это старый, но я просто хотел указать на NETMF (.Net MicroFramework), вы можете легко сделать это:
string response = Resources.GetString(Resources.StringResources.MyFileName);
Так как NETMF не имеет GetManifestResourceStream
Ответ 13
Прочитав все решения, размещенные здесь. Вот как я это решил:
// 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 "";
}
Ответ 14
Меня раздражало, что вы должны всегда включать пространство имен и папку в строке. Я хотел упростить доступ к встроенным ресурсам. Вот почему я написал этот маленький класс. Не стесняйтесь использовать и улучшать!
Применение:
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)));
}
Ответ 15
Ответ довольно прост, просто сделайте это, если вы добавили файл непосредственно из resources.resx.
string textInResourceFile = fileNameSpace.Properties.Resources.fileName;
С этой строкой кода текст из файла непосредственно читается из файла и помещается в строковую переменную.
Ответ 16
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;
}
}
Ответ 17
Некоторые типы проектов VS.NET не генерируют файл .NET(.resx) автоматически. Следующие шаги добавляют файл ресурсов в ваш проект:
- Щелкните правой кнопкой мыши узел проекта и выберите Добавить/Новый элемент, выделите Файл ресурсов. В поле "Имя" выберите подходящее имя, например "Ресурсы", и нажмите кнопку "Добавить".
- Файл ресурсов Resources.resx добавляется в проект и может рассматриваться как узел в обозревателе решений.
- На самом деле, два файла созданы, есть также автоматически сгенерированный С# класс Resources.Designer.cs. Не редактируйте его, он поддерживается VS. Файл содержит класс с именем
Resources
.
Теперь вы можете добавить текстовый файл в качестве ресурса, например, XML файл:
- Дважды щелкните Resources.resx. Выберите Добавить ресурс> Добавить существующий файл и выделите файл, который вы хотите включить. Оставьте значение по умолчанию Internal для Access Modify.
- Значок представляет новый элемент ресурса. Если этот параметр выбран, панель свойств отображает его свойства. Для файлов XML в свойстве Кодировка выберите Unicode (UTF-8) - Кодовая страница 65001 вместо локальной кодовой страницы по умолчанию. Для других текстовых файлов выберите правильную кодировку этого файла, например, кодовую страницу 1252.
- Для текстовых файлов, таких как XML файлы, класс
Resources
имеет свойство типа string
, которое названо в честь включенного файла. Если имя файла, например, RibbonManifest.xml, тогда свойство должно иметь имя RibbonManifest
. Точное имя вы найдете в файле кода Resources.Designer.cs.
- Используйте строковое свойство, как и любое другое строковое свойство, например:
string xml = Resources.RibbonManifest
. Общая форма ResourceFileName.IncludedTextFileName
. Не используйте ResourceManager.GetString
, так как функция get свойства string уже сделала это.
Ответ 18
Чтение встроенного 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 и прочитать их встроенные данные внутри одного богатого текстового поля. который был моим желаемым эффектом с этим образцом кода.