Lesen einer eingebetteten Ressourcentextdatei

693

Wie lese ich eine eingebettete Ressource (Textdatei) mit StreamReaderund gebe sie als Zeichenfolge zurück? Mein aktuelles Skript verwendet ein Windows-Formular und ein Textfeld, mit denen der Benutzer Text in einer nicht eingebetteten Textdatei suchen und ersetzen kann.

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();
}
Me.Close
quelle

Antworten:

1194

Sie können die Assembly.GetManifestResourceStreamMethode verwenden :

  1. Fügen Sie die folgenden Verwendungen hinzu

    using System.IO;
    using System.Reflection;
  2. Eigenschaft der relevanten Datei
    festlegen : Parameter Build Actionmit WertEmbedded Resource

  3. Verwenden Sie den folgenden Code

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

resourceNameist der Name einer der eingebetteten Ressourcen assembly. Zum Beispiel, wenn Sie eine Textdatei mit dem Namen einbetten , "MyFile.txt"die in der Wurzel eines Projektes mit Standard - Namespace platziert wird "MyCompany.MyProduct", dann resourceNameist "MyCompany.MyProduct.MyFile.txt". Mit der Assembly.GetManifestResourceNamesMethode können Sie eine Liste aller Ressourcen in einer Assembly abrufen .


Ein Kinderspiel, um den resourceNameDateinamen nur aus dem Dateinamen zu erhalten ( umgehen Sie das Namespace-Zeug):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));

Ein vollständiges Beispiel:

public string ReadResource(string name)
{
    // Determine path
    var assembly = Assembly.GetExecutingAssembly();
    string resourcePath = name;
    // Format: "{Namespace}.{Folder}.{filename}.{Extension}"
    if (!name.StartsWith(nameof(SignificantDrawerCompiler)))
    {
        resourcePath = assembly.GetManifestResourceNames()
            .Single(str => str.EndsWith(name));
    }

    using (Stream stream = assembly.GetManifestResourceStream(resourcePath))
    using (StreamReader reader = new StreamReader(stream))
    {
        return reader.ReadToEnd();
    }
}
dtb
quelle
5
@ Me.Close: Schauen Sie Environment.SpecialFoldersich den Desktop-Ordner an. Sie müssen berücksichtigen, dass die Ressource basierend auf ihrem Pfad innerhalb des Projekts einen Namespace aufweist, sodass ihr Name möglicherweise nicht gerecht ist file1.txt.
Adrianbanks
15
Das Argument für GetManifestResourceStreambenötigt den Pfad, wie @adrian angibt. Wenn es jemandem hilft, entspricht dieser Pfad dem, was @SimpleCoder im Beispiel zeigt : MyNamespace.Filename.Ext. Ich hatte es zuvor versucht, MyNamespace.Resources.Filename.Extaber das führt zu einer Null.
JYelton
61
Wenn Sie Ihre Ressource nicht direkt im Projektstamm, sondern in einem Unterordner haben, vergessen Sie nicht, diesen Ordnernamen auch in resourceName einzufügen (z. B. "MyProjectNameSpace.MyProjectSubFolder.FileName.FileExtention")
Sasha
19
Es ist erwähnenswert, dass die Ressource "Build Action" als "Embedded Resource" festgelegt werden muss
Illidan
7
Ein wichtiger Punkt, der hier nicht behandelt wird. Wenn Sie Ihre Datei als alternativen Codierungstyp gespeichert haben, um mit ungeraden Zeichen umzugehen (in meinem Fall UTF8), erhalten Sie möglicherweise eine leere Datei zurück, wenn Sie den Stream lesen. Beheben Sie dies, indem Sie den Codierungstyp im Konstruktor des Stream-Readers angeben:using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
Kinetic
140

Sie können eine Datei mit zwei separaten Methoden als Ressource hinzufügen.

Der für den Zugriff auf die Datei erforderliche C # -Code unterscheidet sich je nach der Methode, mit der die Datei zuerst hinzugefügt wurde.

Methode 1: Vorhandene Datei hinzufügen, Eigenschaft auf setzen Embedded Resource

Fügen Sie die Datei Ihrem Projekt hinzu und setzen Sie den Typ auf Embedded Resource.

HINWEIS: Wenn Sie die Datei mit dieser Methode hinzufügen, können Sie GetManifestResourceStreamdarauf zugreifen (siehe Antwort von @dtb ).

Geben Sie hier die Bildbeschreibung ein

Methode 2: Datei hinzufügen zu Resources.resx

Öffnen Sie die Resources.resxDatei, verwenden Sie die Dropdown - Box die Datei hinzuzufügen, Satz Access Modifierzu public.

HINWEIS: Wenn Sie die Datei mit dieser Methode hinzufügen, können Sie Properties.Resourcesdarauf zugreifen (siehe Antwort von @Night Walker ).

Geben Sie hier die Bildbeschreibung ein

Contango
quelle
5
Eine dritte Methode besteht darin, die Datei zum Projekt hinzuzufügen und dann "In Ausgabeverzeichnis kopieren" auf "True" zu setzen. Beim Kompilieren wird die Datei in das Ausgabeverzeichnis kopiert, und Sie können die Datei mit normalen Mitteln lesen. Beispiel: In einer WPF-App, wenn Sie ein Bild anzeigen möchten.
Contango
Wenn Sie also die Build-Aktion auf setzen Resource, können Sie das Element nicht als Ressource auslesen. Sie müssen EmbeddedResourceeine Resources.resxDatei verwenden oder hinzufügen ?
Maslow
3
@Maslow Wenn Sie die Build-Aktion auf "Ressource" setzen, wird eine verknüpfte Ressource erstellt. Wenn Sie die Build-Aktion auf "Eingebettete Ressource" setzen, wird die Ressource in die Ausgabe-Assembly kompiliert. Der Begriff "verknüpfte Ressource" ist ein ausgefallener Begriff für "Kopieren der Datei in das Ausgabeverzeichnis beim Kompilieren" (Sie können die Datei dann zur Laufzeit mit einer beliebigen normalen Methode lesen). Weitere Informationen zum Unterschied zwischen diesen beiden Typen finden Sie unter Hinzufügen und Bearbeiten von Ressourcen (Visual C #) unter msdn.microsoft.com/en-us/library/7k989cfy(v=vs.90).aspx .
Contango
Wenn Sie Ressourcen auf diese Weise, aber dynamisch, verwenden möchten, Properties.Resources.Your_resource_name schreiben Sie Folgendes : Properties.Resources.ResourceManager.GetObject("Your_resource_name").
Lkor
86

Grundsätzlich verwenden Sie System.Reflection, um einen Verweis auf die aktuelle Assembly zu erhalten. Dann benutzt du GetManifestResourceStream().

Beispiel von der Seite, die ich gepostet habe:

Hinweis : Sie müssen hinzufügen, using System.Reflection;damit dies funktioniert

   Assembly _assembly;
   StreamReader _textStreamReader;

   try
   {
      _assembly = Assembly.GetExecutingAssembly();
      _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
   }
   catch
   {
      MessageBox.Show("Error accessing resources!");
   }
Chris Laplante
quelle
32
+1 Für die Aufnahme des namespaceals Teil des Ressourcennamens
Kirk Broadhurst
41
var auxList= System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames(); Diese Methode kann sehr nützlich sein, wenn Sie den genauen Ressourcennamen erfahren möchten. (Entnommen aus Frage stackoverflow.com/questions/27757/… )
Oscar Foley
69

In Visual Studio können Sie den Zugriff auf eine Dateiressource direkt über die Registerkarte Ressourcen der Projekteigenschaften (in diesem Beispiel "Analytics") einbetten. Visual Studio Screenshot - Registerkarte Ressourcen

Auf die resultierende Datei kann dann als Byte-Array von zugegriffen werden

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

Sollten Sie es als Stream benötigen, dann (von https://stackoverflow.com/a/4736185/432976 )

Stream stream = new MemoryStream(jsonSecrets)
Andrew Hill
quelle
11
Sie können dies auch mit einer Textdatei verwenden. In diesem Fall hätten Sie: string jsonSecrets = YourNameSpace.Properties.Resources.YourFileName;
Ouflak
30

Wenn Sie die Datei zu den Ressourcen hinzugefügt haben, sollten Sie die Zugriffsmodifikatoren als öffentlich auswählen, damit Sie Folgendes tun können.

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01 ist der Name der eingebetteten Datei.

Tatsächlich können Sie zu resources.Designer.cs gehen und sehen, wie der Getter heißt.

Nachtwanderer
quelle
5
Könnten Sie das bitte näher erläutern? Wenn ich mit dem rechten Klick-> Eigenschaften auf einer Datei in der Lösung Explorer, und legen Sie Actionauf Incorporated ressource, ich habe kein Access ModifiersFeld im Panel Eigenschaften. Außerdem habe ich keine Propersites.ResourcesKlasse. The name 'Properties' does not exist in the current contextBeim Kompilieren Ihres Codes wird eine Fehlermeldung angezeigt.
Suzanne Dupéron
2
Dies funktioniert nur, wenn Sie die Datei einbetten Resources.resx. Siehe meine Antwort zu den verschiedenen Methoden zum Einbetten von Dateien in ein Projekt.
Contango
13

Hinzufügen zB Testfile.sql Projektmenü -> Eigenschaften -> Ressourcen -> Vorhandene Datei hinzufügen

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

Geben Sie hier die Bildbeschreibung ein

miciry89
quelle
2
Es wird Byte [] zurückgegeben, für Textdateien verwenden Sie "Encoding.UTF8.GetString (Properties.Resources.Testfile)"
MikeTheCoder
12

Ich weiß, dass es ein alter Thread ist, aber das hat bei mir funktioniert:

  1. Fügen Sie die Textdatei zu den Projektressourcen hinzu
  2. Setzen Sie den Zugriffsmodifikator auf public, wie oben von Andrew Hill gezeigt
  3. Lesen Sie den Text folgendermaßen:

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

Der Text, den ich zu den Ressourcen hinzugefügt habe: 'SomeText.txt'

S_Teo
quelle
8

Sie können auch diese vereinfachte Version der Antwort von @ dtb verwenden:

public string GetEmbeddedResource(string ns, string res)
{
    using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", ns, res))))
    {
        return reader.ReadToEnd();
    }
}
Timmerz
quelle
Bist du dir da sicher? Laut diesem Link sieht es so aus, als wäre ich ... stackoverflow.com/questions/1065168/…
Timmerz
8

Ich habe gerade gelernt, dass Ihre Datei kein "" haben darf. (Punkt) im Dateinamen.

EIN "."  im Dateinamen ist nicht gut.

Templates.plainEmailBodyTemplate-de.txt -> Funktioniert !!!
Templates.plainEmailBodyTemplate.en.txt -> funktioniert nicht über GetManifestResourceStream ()

Wahrscheinlich, weil das Framework zwischen Namespaces und Dateinamen verwechselt wird ...

Peter Gfader
quelle
3
Es tut uns leid. Das ist falsch. Punkte funktionieren. (Zumindest hat es bei mir funktioniert, NET4.5) Ich weiß nicht, warum Sie diesen Fehler hatten.
Felix Keil
Ja, sie funktionieren, aber sie fungieren als Verzeichnis-Trennzeichen. Templates.plainEmailBodyTemplate.en.txt sucht nach der Ressource "\ Templates \ plainEmailBodyTemplate \ en.txt"
Peter Gfader
Ich habe es versucht. GetManifestResourceStream kann mit mehr als einem Punkt im Dateinamen auf eingebettete Ressourcen zugreifen. (NET4.5)
Felix Keil
1
Ich hatte das gleiche Problem in .NET 4.5. Dateien mit Punkten im Namen wurden nicht einmal zur Ressourcensammlung hinzugefügt. Die Methodeembly.GetManifestResourceNames () gibt eine leere Liste an mich zurück. Später habe ich herausgefunden, dass das Problem nur mit dem Sprachcode zusammenhängt. ca.abcd.sk.crt wurde nicht zu Ressourcen hinzugefügt, während ca.abcd.crt ohne Probleme hinzugefügt wurde.
a.farkas2508
1
Noch korrekt im Jahr 2020. Vielen Dank dafür, ich wurde verrückt danach.
ZeRemz
8

Bei all Ihren Kräften zusammen verwende ich diese Hilfsklasse, um Ressourcen aus jeder Assembly und jedem Namespace generisch zu lesen.

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();
            }
        }
    }
}
t3chb0t
quelle
3
plus eins für Kapitän Planet: P
Alok
4

Ich habe eine eingebettete Ressourcentextdatei gelesen.

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

Stichprobe:

var template = GetLines(Properties.Resources.LasTemplate /* resource name */);

template.ForEach(ln =>
{
    Debug.WriteLine(ln);
});
Harveyt
quelle
3

Ich weiß, dass dies alt ist, aber ich wollte nur auf NETMF (.Net MicroFramework) hinweisen. Sie können dies einfach tun:

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

Da hat NETMF nichtGetManifestResourceStream

dreamwork801
quelle
3

Nachdem Sie alle hier veröffentlichten Lösungen gelesen haben. So habe ich es gelöst:

// 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 "";      
}
Bill Moore
quelle
3

Die Antwort ist ganz einfach. Tun Sie dies einfach, wenn Sie die Datei direkt aus der Datei resources.resx hinzugefügt haben.

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

Mit dieser Codezeile wird der Text aus der Datei direkt aus der Datei gelesen und in die Zeichenfolgenvariable eingefügt.

Jamisco
quelle
2

Ich war verärgert, dass Sie immer den Namespace und den Ordner in die Zeichenfolge aufnehmen mussten. Ich wollte den Zugriff auf die eingebetteten Ressourcen vereinfachen. Deshalb habe ich diese kleine Klasse geschrieben. Fühlen Sie sich frei zu verwenden und zu verbessern!

Verwendungszweck:

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

Klasse:

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

}
Felix Keil
quelle
1
Und was ist mit der supereinfachen Lösung: var resName = Assembly.GetManifestResourceNames (). Where (i => i.EndsWith (fileName)). FirstOrDefault (); Es wird nicht funktionieren, wenn Sie ganze Verzeichnisse in Assembly zusammenfügen, aber sonst ist es nur eine Zeile;)
Harry
@ Harry sicher, dass Sie dies tun können. Wie korreliert das mit meiner Antwort? Möchten Sie die GetStream-Methode verbessern? Und wie gehen Sie dann mit Mehrdeutigkeiten um?
Felix Keil
1
@Estevez using System; using System.IO; using System.Linq; using System.Reflection;
Felix Keil
2
Aus irgendeinem Grund funktioniert die Klasse nicht, wenn sie in einem anderen Projekt platziert wird. Das Aufrufen und Ausführen von Assemblys bezieht sich beide auf die Assembly mit dieser Klasse, nicht auf die, die tatsächlich Tests ausführt. Ohne statische und träge Initialisierung alles gut, tho.
Curly Brace
1
@ CurlyBrace Danke. Die verzögerte Auswertung ist ein echter Fehler in dieser Antwort, da sich die aufrufenden und ausführenden Assemblys je nach Kontext ändern. Sie müssen bei jedem Zugriff gelöst werden.
Felix Keil
2

Einige VS .NET-Projekttypen generieren keine .NET-Datei (.resx) automatisch. Mit den folgenden Schritten fügen Sie Ihrem Projekt eine Ressourcendatei hinzu:

  1. Klicken Sie mit der rechten Maustaste auf den Projektknoten und wählen Sie Hinzufügen / Neues Element. Scrollen Sie zu Ressourcendatei. Wählen Sie im Feld Name einen geeigneten Namen aus, z. B. Ressourcen, und klicken Sie auf die Schaltfläche Hinzufügen.
  2. Die Ressourcendatei Resources.resx wird dem Projekt hinzugefügt und kann im Lösungs-Explorer als Knoten angesehen werden.
  3. Tatsächlich werden zwei Dateien erstellt, es gibt auch eine automatisch generierte C # -Klasse Resources.Designer.cs. Bearbeiten Sie es nicht, es wird von VS verwaltet. Die Datei enthält eine Klasse mit dem Namen Resources.

Jetzt können Sie eine Textdatei als Ressource hinzufügen, beispielsweise eine XML-Datei:

  1. Doppelklicken Sie auf Resources.resx. Wählen Sie Ressource hinzufügen> Vorhandene Datei hinzufügen und scrollen Sie zu der Datei, die Sie einschließen möchten. Behalten Sie den Standardwert Intern für Zugriff ändern bei.
  2. Ein Symbol steht für das neue Ressourcenelement. Wenn diese Option ausgewählt ist, werden im Eigenschaftenbereich die Eigenschaften angezeigt. Wählen Sie für XML-Dateien unter der Eigenschaft Codierung die Option Unicode (UTF-8) - Codepage 65001 anstelle der lokalen Standardcodepage aus. Wählen Sie für andere Textdateien die richtige Codierung dieser Datei aus, z. B. Codepage 1252.
  3. Bei Textdateien wie XML-Dateien verfügt die Klasse Resourcesüber eine Eigenschaft vom Typ string, die nach der enthaltenen Datei benannt ist. Wenn der Dateiname z. B. RibbonManifest.xml lautet, sollte die Eigenschaft den Namen haben RibbonManifest. Den genauen Namen finden Sie in der Codedatei Resources.Designer.cs.
  4. Verwenden Sie die Zeichenfolgeeigenschaft wie jede andere Zeichenfolgeeigenschaft, zum Beispiel : string xml = Resources.RibbonManifest. Die allgemeine Form ist ResourceFileName.IncludedTextFileName. Nicht verwenden, ResourceManager.GetStringda die get-Funktion der String-Eigenschaft dies bereits getan hat.
Dietrich Baumgarten
quelle
1
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;
    }
}
bytedev
quelle
0

Dies ist eine Klasse, die Sie möglicherweise sehr praktisch finden, um eingebettete Ressourcendateien aus der aktuellen zu lesen Assembly:

using System.IO;
using System.Linq;
using System.Text;
using static System.IO.Path;
using static System.Reflection.Assembly;

public static class EmbeddedResourceUtils
{
    public static string ReadFromResourceFile(string endingFileName)
    {
        var assembly = GetExecutingAssembly();
        var manifestResourceNames = assembly.GetManifestResourceNames();

        foreach (var resourceName in manifestResourceNames)
        {
            var fileNameFromResourceName = _GetFileNameFromResourceName(resourceName);
            if (!fileNameFromResourceName.EndsWith(endingFileName))
            {
                continue;
            }

            using (var manifestResourceStream = assembly.GetManifestResourceStream(resourceName))
            {
                if (manifestResourceStream == null)
                {
                    continue;
                }

                using (var streamReader = new StreamReader(manifestResourceStream))
                {
                    return streamReader.ReadToEnd();
                }
            }
        }

        return null;
    }

    // https://stackoverflow.com/a/32176198/3764804
    private static string _GetFileNameFromResourceName(string resourceName)
    {
        var stringBuilder = new StringBuilder();
        var escapeDot = false;
        var haveExtension = false;

        for (var resourceNameIndex = resourceName.Length - 1;
            resourceNameIndex >= 0;
            resourceNameIndex--)
        {
            if (resourceName[resourceNameIndex] == '_')
            {
                escapeDot = true;
                continue;
            }

            if (resourceName[resourceNameIndex] == '.')
            {
                if (!escapeDot)
                {
                    if (haveExtension)
                    {
                        stringBuilder.Append('\\');
                        continue;
                    }

                    haveExtension = true;
                }
            }
            else
            {
                escapeDot = false;
            }

            stringBuilder.Append(resourceName[resourceNameIndex]);
        }

        var fileName = GetDirectoryName(stringBuilder.ToString());
        return fileName == null ? null : new string(fileName.Reverse().ToArray());
    }
}
BullyWiiPlaza
quelle
0

Für alle Leute, die nur schnell den Text einer fest codierten Datei in Winforms wollen;

  1. Klicken Sie mit der rechten Maustaste auf Ihre Anwendung im Lösungs-Explorer> Ressourcen> Datei hinzufügen.
  2. Klicken Sie darauf und setzen Sie auf der Registerkarte "Eigenschaften" den "Dateityp" auf "Text".
  3. In Ihrem Programm Resources.<name of resource>.toString();lesen Sie einfach die Datei.

Ich würde dies nicht als Best Practice oder so empfehlen, aber es funktioniert schnell und macht das, was es tun muss.

SwatDoge
quelle
0

Für Benutzer, die VB.Net verwenden

Imports System.IO
Imports System.Reflection

Dim reader As StreamReader
Dim ass As Assembly = Assembly.GetExecutingAssembly()
Dim sFileName = "MyApplicationName.JavaScript.js" 
Dim reader = New StreamReader(ass.GetManifestResourceStream(sFileName))
Dim sScriptText = reader.ReadToEnd()
reader.Close()

Wo MyApplicationNameist der Namespace meiner Anwendung? Es ist nicht der Assemblyname. Dieser Name wird in den Projekteigenschaften (Registerkarte Anwendung) definiert.

Wenn Sie den richtigen Ressourcennamen nicht finden, können Sie die GetManifestResourceNames()Funktion verwenden

Dim resourceName() As String = ass.GetManifestResourceNames()

oder

Dim sName As String 
    = ass.GetManifestResourceNames()
        .Single(Function(x) x.EndsWith("JavaScript.js"))

oder

Dim sNameList 
    = ass.GetManifestResourceNames()
        .Where(Function(x As String) x.EndsWith(".js"))
schlebe
quelle
-1

Lesen Sie die eingebettete TXT-Datei beim Laden des Formulars.

Stellen Sie die Variablen dynamisch ein.

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

Rufen Sie einen Try Catch an.

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 für IncludeText () erstellen, Visual Studio erledigt dies für Sie. Klicken Sie auf die Glühbirne, um den CodeBlock automatisch zu generieren.

Fügen Sie Folgendes in den generierten Codeblock ein

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

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

Ressource 3

var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(file3))

using (StreamReader reader = new StreamReader(stream))
{
    string result3 = reader.ReadToEnd();
    richTextBox1.AppendText(result3);
}

Wenn Sie die zurückgegebene Variable an einen anderen Ort senden möchten, rufen Sie einfach eine andere Funktion auf und ...

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

}

Dies wurde erreicht, eine Methode, um mehrere txt-Dateien zu kombinieren und ihre eingebetteten Daten in einem einzigen Rich-Text-Feld zu lesen. Das war mein gewünschter Effekt mit diesem Code-Beispiel.

MasterCassidy
quelle