Cómo leer el archivo de texto de recurso incrustado

¿Cómo leo un recurso incrustado (archivo de texto) usando StreamReader y lo devuelvo como una cadena? Mi script actual usa un formulario y un cuadro de texto de Windows que le permite al usuario encontrar y reemplazar texto en un archivo de texto que no está incrustado.

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

Puede usar el método Assembly.GetManifestResourceStream :

  1. Agregue los siguientes usos

     using System.IO; using System.Reflection; 
  2. Establecer propiedad del archivo relevante:
    Parámetro Build Action con valor Embedded Resource

  3. Usa el siguiente código

 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 es el nombre de uno de los recursos integrados en el assembly . Por ejemplo, si "MyFile.txt" un archivo de texto llamado "MyFile.txt" que se coloca en la raíz de un proyecto con el espacio de nombre predeterminado "MyCompany.MyProduct" , entonces resourceName es "MyCompany.MyProduct.MyFile.txt" . Puede obtener una lista de todos los recursos en un ensamblado utilizando el método Assembly.GetManifestResourceNames .

Puede agregar un archivo como recurso usando dos métodos separados.

El código de C # requerido para acceder al archivo es diferente , dependiendo del método utilizado para agregar el archivo en primer lugar.

Método 1: Agregue el archivo existente, establezca la propiedad como Embedded Resource

Agregue el archivo a su proyecto, luego configure el tipo de Embedded Resource .

NOTA: Si agrega el archivo utilizando este método, puede usar GetManifestResourceStream para acceder a él (vea la respuesta de @dtb).

enter image description here

Método 2: Agregar archivo a Resources.resx

Abra el archivo Resources.resx , use el cuadro desplegable para agregar el archivo y configure el Access Modifier como public .

NOTA: Si agrega el archivo con este método, puede usar Properties.Resources para acceder a él (vea la respuesta de @Night Walker).

enter image description here

Eche un vistazo a esta página: http://support.microsoft.com/kb/319292

Básicamente, usa System.Reflection para obtener una referencia al Assembly actual. Luego, usa GetManifestResourceStream() .

Ejemplo, de la página que publiqué:

Nota : necesita agregar using System.Reflection; para que esto funcione

  Assembly _assembly; StreamReader _textStreamReader; try { _assembly = Assembly.GetExecutingAssembly(); _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt")); } catch { MessageBox.Show("Error accessing resources!"); } 

En Visual Studio puede incrustar directamente el acceso a un recurso de archivo a través de la pestaña Recursos de las propiedades del Proyecto (“Analíticas” en este ejemplo). Captura de pantalla visual studio - pestaña Recursos

El archivo resultante se puede acceder como una matriz de bytes por

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

En caso de que lo necesites como una secuencia, entonces (de https://stackoverflow.com/a/4736185/432976 )

 Stream stream = new MemoryStream(jsonSecrets) 

Cuando agregaste el archivo a los recursos, debes seleccionar sus modificadores de acceso como públicos, de lo que puedes hacer algo como lo siguiente.

 byte[] clistAsByteArray = Properties.Resources.CLIST01; 

CLIST01 es el nombre del archivo incrustado.

En realidad, puedes ir a resources.Designer.cs y ver cuál es el nombre del getter.

Sé que es un hilo viejo, pero esto es lo que funcionó para mí:

  1. agregue el archivo de texto a los recursos del proyecto
  2. establecer el modificador de acceso en público, como se muestra arriba por Andrew Hill
  3. lee el texto así:

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

El texto que agregué a los recursos: ‘SomeText.txt’

También puede usar esta versión simplificada de la respuesta de @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(); } } 

Algo que aprendí ahora es que su archivo no puede tener un “.” (punto) en el nombre del archivo.

UN

Templates.plainEmailBodyTemplate-en.txt -> Funciona!
Templates.plainEmailBodyTemplate.en.txt -> no funciona a través de GetManifestResourceStream ()

Probablemente porque el marco se confunde sobre espacios de nombres vs nombre de archivo …

agregando, por ejemplo, Testfile.sql Project Menu -> Propiedades -> Recursos -> Agregar archivo existente

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

Leí un uso de archivo de texto de recurso incrustado:

  ///  /// Converts to generic list a byte array ///  /// byte array (embedded resource) /// generic list of strings private List GetLines(byte[] content) { string s = Encoding.Default.GetString(content, 0, content.Length - 1); return new List(s.Split(new[] { Environment.NewLine }, StringSplitOptions.None)); } 

Muestra:

 var template = GetLines(Properties.Resources.LasTemplate /* resource name */); template.ForEach(ln => { Debug.WriteLine(ln); }); 

Con todos tus poderes combinados utilizo esta clase de ayuda para leer recursos de cualquier ensamblaje y cualquier espacio de nombres de una manera genérica.

 public class ResourceReader { public static IEnumerable FindEmbededResources(Func predicate) { if (predicate == null) throw new ArgumentNullException(nameof(predicate)); return GetEmbededResourceNames() .Where(predicate) .Select(name => ReadEmbededResource(typeof(TAssembly), name)) .Where(x => !string.IsNullOrEmpty(x)); } public static IEnumerable GetEmbededResourceNames() { var assembly = Assembly.GetAssembly(typeof(TAssembly)); return assembly.GetManifestResourceNames(); } public static string ReadEmbededResource(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(); } } } } 

Sé que esto es antiguo, pero solo quería señalar NETMF (.Net MicroFramework), puede hacer esto fácilmente:

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

Como NETMF no tiene GetManifestResourceStream

Me molestaba que siempre tuviera que incluir el espacio de nombres y la carpeta en la cadena. Quería simplificar el acceso a los recursos integrados. Es por eso que escribí esta pequeña clase. ¡Siéntete libre de usar y mejorar!

Uso:

 using(Stream stream = EmbeddedResources.ExecutingResources.GetStream("filename.txt")) { //... } 

Clase:

 public class EmbeddedResources { private static readonly Lazy _callingResources = new Lazy(() => new EmbeddedResources(Assembly.GetCallingAssembly())); private static readonly Lazy _entryResources = new Lazy(() => new EmbeddedResources(Assembly.GetEntryAssembly())); private static readonly Lazy _executingResources = new Lazy(() => 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))); } 

Después de leer todas las soluciones publicadas aquí. Así es como lo resolví:

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

Lea ARCHIVO TXT incrustado en Evento de carga de formulario.

Establezca las variables dinámicamente.

 string f1 = "AppName.File1.Ext"; string f2 = "AppName.File2.Ext"; string f3 = "AppName.File3.Ext"; 

Llame a 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. } 

Create Void for IncludeText (), Visual Studio hace esto por usted. Haga clic en la bombilla para Autogenerar el CodeBlock.

Coloque lo siguiente dentro del bloque de código generado

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

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

Recurso 3

 var assembly = Assembly.GetExecutingAssembly(); using (Stream stream = assembly.GetManifestResourceStream(file3)) using (StreamReader reader = new StreamReader(stream)) { string result3 = reader.ReadToEnd(); richTextBox1.AppendText(result3); } 

Si desea enviar la variable devuelta a otro lugar, simplemente llame a otra función y …

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

Lo que esto logró fue esto, un método para combinar múltiples archivos txt, y leer sus datos incrustados, dentro de un único cuadro de texto enriquecido. cual fue mi efecto deseado con esta muestra de Código.