Reputation: 15061
I have tried multiple solutions on here but non of them I can get to work. All i want to do is read a text file from my resources folder rather than the actual local folder.
File name: TextFile.txt
Set to embedded resource.
"Local File" Code that works:
string[] spaces = File.ReadAllLines("C:\\Users\\a\\source\\repos\\a\\bin\\Debug\\TextFile.txt");
Current Code:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
But I am getting the following error:
System.ArgumentNullException: 'Value cannot be null. Parameter name: stream'
On this line:
using (StreamReader reader = new StreamReader(stream))
EDIT1 Tried this as per link (Why does GetManifestResourceStream returns null while the resource name exists when calling GetManifestResourceNames?) and this NULL ERROR:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "programname.TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
Same error, am I putting the namespace bit in the wrong place?
Edit 2, tried this:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "programname.Resources.TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
New error:
System.IO.FileNotFoundException: 'Could not find file 'C:\Users\a\source\repos\a\bin\Debug\programname.Resources.TextFile.txt'.'
Location of TextFile.txt
programname
Resources
TextFile.txt
Upvotes: 1
Views: 3412
Reputation: 15061
Got this to work by opening Resources.resx
, Setting Access Modifier
to Public
Then adding the file in there.
Then replaced:
string[] spaces = File.ReadAllLines("C:\\Users\\a\\source\\repos\\a\\bin\\Debug\\TextFile.txt")
With:
var resourceText = Properties.Resources.TextFile;
var Lines= resourceText.Replace("\r", "").Split('\n');
A little background:
MSDN:
If you add a resource to your project in the normal way, it will automatically provide a typesafe wrapper for that resource.
For example, in the Solution Explorer, expand the "Properties" node and double click the "Resources.resx" entry. Then add an image via the "Add Resource" button. Give that resource a name, say "MyImage".
You will then be able to programmatically access that image via "Properties.Resources.MyImage"
Note that the names are stripped of the extension and, as other c# names, are case-sensitive!
To use them you can't use a code as simple as the one above. Instead you need to find out the name (Intellisense will not help you there) and them use calls to the Reflection
namespace.
Note that here the names are __not_- stripped of the extension but still are case-sensitive!
Example:
If we don't know the exact name we can search in the assembly:
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var ress = assembly.GetManifestResourceNames()
.Where(x => x.Contains(somepattern)).First();
Usually the 1st way is much recommended. Typesafety and Intellisense support alone are well worth mainainting the resx file! Now we can open a stream to read the resource:
List<string> results = new List<string>(); ;
using (Stream stream = assembly.GetManifestResourceStream(ress))
using (StreamReader reader = new StreamReader(stream))
{
while (reader.Peek()>=0) results.Add(reader.ReadLine());
}
Upvotes: 3
Reputation: 407
This function will return the correct resource name for your file:
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("TextFile.txt"));
2nd issue:
For string[] spaces = File.ReadAllLines(resourceName);
You can't use the same resourceName (embedded resource). If you need to read text line by line use for example:
using (StreamReader reader = new StreamReader(stream))
{
while (reader.Peek() >= 0)
{
Console.WriteLine(reader.ReadLine());
}
}
Upvotes: 2