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();
}
15 réponses
vous pouvez utiliser le Assembly.GetManifestResourceStream
méthode :
-
ajouter les utilisations suivantes
using System.IO; using System.Reflection;
-
Définir une propriété de fichier:
ParamètreBuild Action
avec valeurEmbedded Resource
-
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 .
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).
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.)
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!");
}
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).
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)
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.
je sais que c'est un vieux thread, mais c'est ce qui a fonctionné pour moi :
- ajouter le fichier texte aux ressources du projet
- définir le modificateur d'accès public, comme l'ont montré ci-dessus par Andrew Hill
-
lisez le texte comme ceci:
textBox1 = new TextBox(); textBox1.Text = Properties.Resources.SomeText;
le texte que j'ai ajouté aux ressources: "SomeText.txt '
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();
}
}
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.
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...
ajouter par exemple Testfile.SQL Menu du projet - > Propriétés -> ressources - > Ajouter un fichier existant
string queryFromResourceFile = Properties.Resources.Testfile.ToString();
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);
});
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();
}
}
}
}
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
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)));
}
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 "";
}
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" 1var 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.