Как прочитать встроенный ресурс (текстовый файл) с помощью 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();
}
Вы можете использовать метод 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
.
Вы можете добавить файл в качестве ресурса, используя два отдельных метода.
Код С#, необходимый для доступа к файлу, отличается, в зависимости от метода, используемого для добавления файла в первую очередь.
Embedded Resource
Добавьте файл в свой проект, затем установите тип Embedded Resource
.
ПРИМЕЧАНИЕ. Если вы добавите файл с помощью этого метода, вы можете использовать GetManifestResourceStream
для доступа к нему (см. ответ от @dtb).
Resources.resx
Откройте файл Resources.resx
, используйте раскрывающийся список, чтобы добавить файл, установите Access Modifier
на public
.
ПРИМЕЧАНИЕ. Если вы добавите файл с помощью этого метода, вы можете использовать Properties.Resources
для доступа к нему (см. ответ от @Night Walker).
Resource
не делает ничего, что позволяет считывать элемент как ресурс? Вы должны использовать EmbeddedResource
или добавить в файл Resources.resx
?
Взгляните на эту страницу: 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!");
}
namespace
как части имени ресурса
var auxList= System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
Этот метод может быть очень полезен, когда вы хотите узнать точное имя ресурса. (Взято из вопроса stackoverflow.com/questions/27757/… )
В Visual Studio вы можете напрямую встраивать доступ к файловому ресурсу через вкладку "Ресурсы" свойств проекта ( "Аналитика" в этом примере).
После этого результирующий файл можно получить в виде байтового массива с помощью
byte[] jsonSecrets = GoogleAnalyticsExtractor.Properties.Resources.client_secrets_reporter;
Если вам нужно это как поток, то (из https://stackoverflow.com/questions/4736155/how-do-i-convert-byte-to-stream-in-c)
Stream stream = new MemoryStream(jsonSecrets)
Когда вы добавили файл в ресурсы, вы должны выбрать его модификаторы доступа как общедоступные, чем вы можете сделать следующее.
byte[] clistAsByteArray = Properties.Resources.CLIST01;
CLIST01 - это имя встроенного файла.
На самом деле вы можете перейти к resources.Designer.cs и посмотреть, что такое имя получателя.
Action
для Incorporated ressource
, у меня нет поля « Access Modifiers
на панели свойств. Кроме того, у меня нет класса Propersites.Resources
, я получаю The name 'Properties' does not exist in the current context
ошибки при компиляции вашего кода.
Resources.resx
, см. Мой ответ о различных методах встраивания файлов в проект.
Я знаю, что это старый поток, но это то, что сработало для меня:
прочитайте текст следующим образом:
textBox1 = new TextBox();
textBox1.Text = Properties.Resources.SomeText;
Текст, который я добавил в ресурсы: 'SomeText.txt'
Что-то, что я узнал сейчас, это то, что вашему файлу не разрешено иметь ".". (точка) в имени файла.
Templates.plainEmailBodyTemplate-en.txt → Работает!!!
Templates.plainEmailBodyTemplate.en.txt → не работает через GetManifestResourceStream()
Возможно, из-за того, что структура запуталась в пространствах имен vs filename...
Вы также можете использовать эту упрощенную версию ответа @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();
}
}
добавление, например. Testfile.sql Меню проекта → Свойства → Ресурсы → Добавить существующий файл
string queryFromResourceFile = Properties.Resources.Testfile.ToString();
Со всеми вашими полномочиями я использую этот вспомогательный класс для чтения ресурсов из любой сборки и любого пространства имен общим способом.
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();
}
}
}
}
Я прочитал использование встроенного текстового файла ресурсов:
/// <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);
});
Меня раздражало, что вы должны всегда включать пространство имен и папку в строке. Я хотел упростить доступ к встроенным ресурсам. Вот почему я написал этот маленький класс. Не стесняйтесь использовать и улучшать!
Применение:
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)));
}
Я знаю, что это старый, но я просто хотел указать на NETMF (.Net MicroFramework), вы можете легко сделать это:
string response = Resources.GetString(Resources.StringResources.MyFileName);
Так как NETMF не имеет GetManifestResourceStream
Прочитав все решения, размещенные здесь. Вот как я это решил:
// 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 "";
}
string f1 = "AppName.File1.Ext";
string f2 = "AppName.File2.Ext";
string f3 = "AppName.File3.Ext";
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.
}
Поместите следующее внутри блока сгенерированного кода
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 );
}
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 );
}
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 и прочитать их встроенные данные внутри одного богатого текстового поля. который был моим желаемым эффектом с этим образцом кода.
Environment.SpecialFolder
чтобы получить папку на рабочем столе. Вы должны иметь в виду, что ресурс будет иметь пространство имен на основе его пути в проекте, поэтому его имя может быть не простоfile1.txt
.