Manifestresource stream load gives null reference expection on some files - c#

I'm doing a Xamarin project and having this problem and I don't know how to fix it.
I'm trying to get some data from a .txt file. I've already fixed it and it works on one of the files, but when I switch to another file it suddenly gives me NullReferenceException.
Here's the code that works:
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(ReadFromTxtFile)).Assembly;
Stream stream = assembly.GetManifestResourceStream("HanafiSalahTider.salahtider2019.txt");
using (StreamReader myreader = new StreamReader(stream))
{
fileContent = myreader.ReadToEnd();
}
Here's the nonworking code:
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(ReadFromTxtFile)).Assembly;
Stream stream = assembly.GetManifestResourceStream("HanafiSalahTider.salahtider.txt");
using (StreamReader myreader = new StreamReader(stream))
{
fileContent = myreader.ReadToEnd();
}
Here's both files in the solution explorer:

To be able to load a manifest resource, the Build Action of that file needs to be set to Embedded Resource. To check this, select the file, right click on it a select Properties. In the properties window, change the Build Action to Embedded Resource.

Related

how to access files in xamarin.android. And also in Visual Studio Solution explorer where should i place the file in order to locate it in my code

The code below tries to access file named zimbabwe in Asset folder
var fileContent = File.ReadAllText("Asset/zimbabwe.shp")
How should I access files in xamarin.android? And also in Visual Studio Solution explorer where should I place the file in order to locate it in my code?
In Xamarin.Android project, Assets are read using an AssetManager. An instance of the AssetManager is available by accessing the Assets property on an Android.Content.Context, such as an Activity.
For example:
string content;
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("zimbabwe.shp")))
{
content = sr.ReadToEnd ();
}
And in Xamarin.Forms project,you could also add any file into the Assets folder in the Android project and mark the Build Action as AndroidAsset to use it with OpenAppPackageFileAsync.
using (var stream = await FileSystem.OpenAppPackageFileAsync(templateFileName))
{
using (var reader = new StreamReader(stream))
{
var fileContents = await reader.ReadToEndAsync();
}
}

C# Read text file from resources rather than locally error, adding namespace didnt work

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
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"
This is the simple and recommended way; it will let you edit the name in the resource file and will check while coding that the name is correct.
Note that the names are stripped of the extension and, as other c# names, are case-sensitive!
The other way doesn't register the resources with the .resx file but only add them to the resource folder and marks them as embedded.
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());
}
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());
}
}

How to read a resource file in C#

I have added a resource file to my project (C#, windows service - TopShelp):
I have added a text file to the resource:
Now I want to read the test file, this is what I have tried:
ResourceManager rm = new ResourceManager("My.Project.Name.Resources", Assembly.GetExecutingAssembly());
It does not find anything, ResourceSets count = 0.
Update
As suggested in the comments, I also tried adding the resource under:
Project > Properties > Resources
And tried the following code, which did not find anything:
ResourceManager rm = new ResourceManager("My.Project.Name.Resources", Assembly.GetExecutingAssembly());
Check your Resources.Designer.cs file. You should have there static string property named stop_words_utf8 (or whatever name for the file you choose). You use it like this:
Resources.stop_words_utf8
It is static string property
You can always try:
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();
}
Check that your file exists through Assembly.GetManifestResourceNames method.

Reading a file from resources

I have embed sample.txt(it contains just one line "aaaa" ) file into project's resources like in this answer.
When I'm trying to read it like this:
string s = File.ReadAllText(global::ConsoleApplication.Properties.Resources.sample);
I'm getting System.IO.FileNotFoundException' exception.
Additional information: Could not find file 'd:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\bin\Debug\aaaa'.
So seemingly it's trying to take file name from my resource file instead of reading this file. Why is this happening? And how can I make it read sample.txt
Trying solution of #Ryios and getting Argument null exception
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication.Resources.sample.txt"))
{
TextReader tr = new StreamReader(stream);
string fileContents = tr.ReadToEnd();
}
The file is located in d:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\Resources\sample.txt
p.s. Solved. I had to set Build Action - embed resource in sample.txt properties
You can't read Resource Files with File.ReadAllText.
Instead you need to open a Resource Stream with Assembly.GetManifestResourceStream.
You don't pass it a path either, you pass it a namespace. The namespace of the file will be the Assemblies Default Namespace + The folder heieracy in the project the file is in + the name of the file.
Imagine this structure
Project (xyz.project)
Folder1
Folder2
SomeFile.Txt
So the namespace for the file will be:
xyz.project.Folder1.Folder2.SomeFile.Txt
Then you would read it like so
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt"))
{
TextReader tr = new StreamReader(stream);
string fileContents = tr.ReadToEnd();
}
Hello the proposed solution doesn't work
This return null:
Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt")
Another way is to use a MemoryStream from the Ressource Data:
byte[] aa = Properties.Resources.YOURRESSOURCENAME;
MemoryStream MS =new MemoryStream(aa);
StreamReader sr = new StreamReader(MS);
Not ideal but it works

Reading embedded XML file c#

How can I read from an embedded XML file - an XML file that is part of a c# project?
I've added a XML file to my project and I want to read from it. I want the XML file to compile with the project because I don't want that it will be a resource which the user can see.
Any idea?
Make sure the XML file is part of your .csproj project. (If you can see it in the solution explorer, you're good.)
Set the "Build Action" property for the XML file to "Embedded Resource".
Use the following code to retrieve the file contents at runtime:
public string GetResourceTextFile(string filename)
{
string result = string.Empty;
using (Stream stream = this.GetType().Assembly.
GetManifestResourceStream("assembly.folder."+filename))
{
using (StreamReader sr = new StreamReader(stream))
{
result = sr.ReadToEnd();
}
}
return result;
}
Whenever you want to read the file contents, just use
string fileContents = GetResourceTextFile("myXmlDoc.xml");
Note that "assembly.folder" should be replaced with the project name and folder containing the resource file.
Update
Actually, assembly.folder should be replaced by the namespace in which a class created in the same folder as the XML file would have by default. This is typically defaultNamespace.folder0.folder1.folder2......
You can also add the XML file as a Resource and then address its contents with Resources.YourXMLFilesResourceName (as a string, i.e. using a StringReader).
Set the Build Action to Embedded Resource, then write the following:
using (Stream stream = typeof(MyClass).Assembly.GetManifestResourceStream("MyNameSpace.Something.xml")) {
//Read the stream
}
You can use Reflector (free from http://www.red-gate.com/products/reflector/) to find the path to the embedded XML file.
Then, it's just a matter of
Assembly a = typeof(Assembly.Namespace.Class).Assembly;
Stream s = a.GetManifestResourceStream("Assembly.Namespace.Path.To.File.xml");
XmlDocument mappingFile = new XmlDocument();
mappingFile.Load(s);
s.Close();
Add the file to the project.
Set the "Build Action" property to "Embedded Resource".
Access it this way:
GetType().Module.Assembly.GetManifestResourceStream("namespace.folder.file.ext")
Notice that the resource name string is the name of the file,
including extension, preceded by the default namespace of the project.
If the resource is inside a folder, you also have to include it in the
string.
(from http://www.dotnet247.com/247reference/msgs/1/5704.aspx, but I used it pesonally)
#3Dave really helped (up vote given), however my resource helper was in a different assembly so I did the below
public string GetResourceFileText(string filename, string assemblyName)
{
string result = string.Empty;
using (Stream stream =
System.Reflection.Assembly.Load(assemblyName).GetManifestResourceStream($"{assemblyName}.{filename}"))
{
using (StreamReader sr = new StreamReader(stream))
{
result = sr.ReadToEnd();
}
}
return result;
}
Called by
GetResourceFileText("YourFileNameHere.ext", Assembly.GetExecutingAssembly().GetName().Name);

Categories