864 Stimmen

Wie lese ich eine eingebettete Ressource-Textdatei?

Wie lese ich eine eingebettete Ressource (Textdatei) mit StreamReader und als Zeichenkette zurückgeben? Mein aktuelles Skript verwendet ein Windows-Formular und ein Textfeld, mit dem 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();
}

3voto

Matteo Gariglio Punkte 456

Wie von SonarCloud angegeben, besser zu tun:

public class Example
{
    public static void Main()
    { 
        // Compliant: type of the current class
        Assembly assembly = typeof(Example).Assembly; 
        Console.WriteLine("Assembly name: {0}", assem.FullName);

        // Non-compliant
        Assembly assembly = Assembly.GetExecutingAssembly();
        Console.WriteLine("Assembly name: {0}", assem.FullName);
    }
}

3voto

Jamisco Punkte 1365

Die Antwort ist ganz einfach, tun Sie dies einfach, wenn Sie die Datei direkt aus der 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 String-Variable eingesetzt.

0 Stimmen

Das gibt ein Byte-Array und keinen String zurück

0 Stimmen

@Elnoor Ich glaube nicht, dass dies wahr ist oder zumindest nicht wahr mit allen Versionen. von .NetCore/Framework. Ich habe dies mit .Net 4.0 getestet und fileNameSpace.Properties.Resources.fileName; ist ein String-Typ.

0 Stimmen

Ich habe in Core getestet. Vielleicht wird in Net standard yeah string zurückgegeben

2voto

bytedev Punkte 6692
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;
    }
}

// To use the code above:
var reader = new AssemblyTextFileReader(assembly);

string text = await reader.ReadFileAsync(@"MyFile.txt");

2voto

Saeb Amini Punkte 20943

Ich wollte die eingebettete Ressource nur als Byte-Array lesen (ohne eine bestimmte Kodierung anzunehmen), und ich endete mit einer MemoryStream was es sehr einfach macht:

using var resStream = assembly.GetManifestResourceStream(GetType(), "file.txt");
var ms = new MemoryStream();
await resStream .CopyToAsync(ms);
var bytes = ms.ToArray();

1voto

Felix Keil Punkte 2188

Es hat mich gestört, dass man immer den Namespace und den Ordner in den String einfügen musste. Ich wollte den Zugriff auf die eingebetteten Ressourcen vereinfachen. Deshalb habe ich diese kleine Klasse geschrieben. Fühlen Sie sich frei, sie zu benutzen und zu verbessern!

Uso:

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

}

2 Stimmen

Und wie wäre es mit einer supereinfachen Lösung: var resName = assembly.GetManifestResourceNames().Where(i => i.EndsWith(fileName)).FirstOrDefault(); Es wird nicht funktionieren, wenn Sie ganze Verzeichnisse in Assembly platzieren, aber ansonsten ist es nur eine Zeile ;)

0 Stimmen

@Harry sicher können Sie dies tun. Was hat das mit meiner Antwort zu tun? Willst du die GetStream Methode verbessern? Und wie gehen Sie dann mit Zweideutigkeit um?

0 Stimmen

Ja, ich wollte eine kleine Verbesserung vornehmen. OK: var a = Assembly.GetExecutingAssembly(); using (var s = a.GetManifestResourceStream($"{a.EntryPoint.ReflectedType.Namespace}.{name}")) { /* hier den Stream verwenden */ } - hier ist der Weg, um Mehrdeutigkeit zu behandeln, scheint wie wir Namespace irgendwo verwenden müssen. Ich habe nur nach einem kürzeren und kompakteren Weg gesucht, um zu MRS zu gelangen, am besten ohne Abhängigkeit außerhalb der Methode. Ich bin nicht sicher, ob es nützlich ist, obwohl, wie auch immer ich in meinem Selbst-Extraktor verwendet, so dass ich teilen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X