Comment lire un fichier texte de ressource intégré

Comment puis-je lire une ressource intégrée (fichier texte) en utilisant StreamReader et la retourner sous forme de chaîne de caractères? Mon script actuel utilise une forme Windows et une zone de texte qui permet à l'utilisateur de trouver et de remplacer du texte dans un fichier texte qui n'est pas intégré.

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();
}
544
demandé sur Alex Jolig 2010-07-23 02:51:15

15 réponses

vous pouvez utiliser le Assembly.GetManifestResourceStream méthode :

  1. ajouter les utilisations suivantes

    using System.IO;
    using System.Reflection;
    
  2. Définir une propriété de fichier:

    Paramètre Build Action avec valeur Embedded Resource

  3. utilisez le code suivant

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 est le nom d'une des ressources intégrées dans assembly . Par exemple , si vous avez intégré un fichier texte nommé "MyFile.txt" qui est placé dans la racine d'un projet avec l'espace de nom par défaut "MyCompany.MyProduct" , alors resourceName est "MyCompany.MyProduct.MyFile.txt" . Vous pouvez obtenir une liste de toutes les ressources dans une assemblée en utilisant le Assembly.GetManifestResourceNames méthode .

929
répondu dtb 2018-03-04 10:15:25

vous pouvez ajouter un fichier comme ressource en utilisant deux méthodes distinctes.

le code C requis pour accéder au fichier est différent , selon la méthode utilisée pour ajouter le fichier en premier lieu.

Méthode 1: Ajouter fichier existant, définir propriété à Embedded Resource

ajoutez le fichier à votre projet, puis définissez le type à Embedded Resource .

NOTE: Si vous ajoutez le fichier en utilisant cette méthode, vous pouvez utiliser GetManifestResourceStream pour y accéder (voir la réponse de @dtb).

enter image description here

Méthode 2: Ajouter fichier à Resources.resx

ouvrez le fichier Resources.resx , utilisez la boîte déroulante pour ajouter le fichier, mettez Access Modifier à public .

NOTE: Si vous ajoutez le fichier en utilisant cette méthode, vous pouvez utiliser Properties.Resources pour y accéder (voir la réponse de @Night Walker.)

enter image description here

110
répondu Contango 2014-10-27 10:10:40

regardez cette page: http://support.microsoft.com/kb/319292

en gros, vous utilisez System.Reflection pour obtenir une référence à l'assemblage actuel. Ensuite, vous utilisez GetManifestResourceStream() .

exemple, de la page j'ai posté:

Note : il faut ajouter using System.Reflection; pour que cela fonctionne

   Assembly _assembly;
   StreamReader _textStreamReader;

   try
   {
      _assembly = Assembly.GetExecutingAssembly();
      _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
   }
   catch
   {
      MessageBox.Show("Error accessing resources!");
   }
84
répondu Chris Laplante 2010-07-22 23:01:24

dans Visual Studio, vous pouvez directement intégrer l'accès à une ressource de fichier via l'onglet Ressources des propriétés du projet ("Analytics" dans cet exemple). visual studio screen shot - Resources tab

le fichier résultant peut alors être accédé comme un tableau d'octets par

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

si vous en avez besoin comme un ruisseau, alors (de https://stackoverflow.com/a/4736185/432976 )

Stream stream = new MemoryStream(jsonSecrets)
65
répondu Andrew Hill 2017-05-23 12:02:56

Lorsque vous avez ajouté le fichier de ressources, vous devez sélectionner ses Modificateurs d'Accès public que vous pouvez faire quelque chose comme suit.

byte[] clistAsByteArray = Properties.Resources.CLIST01;

CLIST01 est le nom du fichier intégré.

en fait, vous pouvez aller aux ressources.Designer.cs et de voir quel est le nom de l'acquéreur.

26
répondu Night Walker 2016-08-12 20:42:27

je sais que c'est un vieux thread, mais c'est ce qui a fonctionné pour moi :

  1. ajouter le fichier texte aux ressources du projet
  2. définir le modificateur d'accès public, comme l'ont montré ci-dessus par Andrew Hill
  3. lisez le texte comme ceci:

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

le texte que j'ai ajouté aux ressources: "SomeText.txt '

12
répondu S_Teo 2013-12-30 14:29:46

vous pouvez également utiliser cette version simplifiée de la réponse 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();
    }
}
7
répondu Timmerz 2013-07-08 19:14:35

quelque chose que j'ai appris tout à l'heure est que votre dossier n'est pas autorisé à avoir un "."(point) dans le nom de fichier.

A "." in filename is no good.

Templates.plainEmailBodyTemplate-en.txt -- > fonctionne!!!

Modèle.plainEmailBodyTemplate.fr.txt --> ne fonctionne pas via GetManifestResourceStream ()

probablement parce que le framework se confond sur namespaces vs filename...

7
répondu Peter Gfader 2015-07-03 17:28:58

ajouter par exemple Testfile.SQL Menu du projet - > Propriétés -> ressources - > Ajouter un fichier existant

    string queryFromResourceFile = Properties.Resources.Testfile.ToString();
5
répondu miciry89 2017-03-14 19:25:28

j'ai lu une ressource intégrée utilisation du fichier texte:

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

échantillon:

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

template.ForEach(ln =>
{
    Debug.WriteLine(ln);
});
4
répondu harveyt 2016-11-23 08:34:58

par tous vos pouvoirs combinés j'utilise cette classe helper pour lire des ressources de n'importe quelle assemblée et n'importe quel espace de nom d'une manière générique.

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();
            }
        }
    }
}
4
répondu t3chb0t 2017-02-11 17:09:39

je sais que c'est vieux, mais je voulais juste souligner pour NETMF (. Microfram Framework), vous pouvez facilement faire ceci:

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

Depuis NETMF n'a pas GetManifestResourceStream

3
répondu dreamwork801 2015-09-17 06:50:11

j'ai été ennuyé que vous deviez toujours inclure l'espace de noms et le dossier dans la chaîne de caractères. J'ai voulu simplifier l'accès aux ressources intégrées. C'est pourquoi j'ai écrit ce petit de la classe. N'hésitez pas à utiliser et l'améliorer!

Utilisation:

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

Classe:

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

}
3
répondu Felix Keil 2018-06-13 15:25:54

après avoir lu toutes les solutions postées ici. Voici comment je l'ai résolu:

// 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 "";      
}
2
répondu Bill Moore 2017-09-26 22:49:11

lire le fichier txt intégré à L'événement de chargement du formulaire.

définit les Variables de façon dynamique.

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

appelle un "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.
}

créer vide pour IncludeText (), Visual Studio le fait pour vous. Cliquez sur L'Ampoule pour Autogénérer le CodeBlock.

mettez ce qui suit dans le bloc de Code généré

"151960920 de 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 );
}
"151960920 de 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 );
}
"151960920 de 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);
}

si vous souhaitez envoyer la variable retournée ailleurs, appelez simplement une autre fonction et...

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

}

ce que cela a permis était ceci, une méthode pour combiner plusieurs fichiers txt, et lire leurs données intégrées, à l'intérieur d'une seule boîte de texte riche. ce qui était mon effet désiré avec cet échantillon de Code.

0
répondu MasterCassidy 2016-08-07 10:33:23