Xamarin Android System.IO.FileNotFoundException: Could not find file Exception - c#

I use Visual Studio 2015 with Xamarin Android.
I want to read some JSON data from file, but I keep getting this System.IO.FileNotFoundException, even though I have set my files properties "Build: Content, Copy to Output Directory: Copy if newer" and I can see the file physically in my build folder.
I use this code:
var path = #"AedJson.json";
using (var streamReader = new StreamReader(path))
{
string json = streamReader.ReadToEnd();
//JObject o1 = JObject.Parse(json);
}
The exact exception is:
System.IO.FileNotFoundException: Could not find file "/AedJson.json".
Error Picture

You need to add your json file to your Xamarin.Android project as an Asset (within the Assets folder) and flag it as an AndroidAsset build type, then you can use the AssetManager to read it.
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("AedJson.json")))
{
string json = sr.ReadToEnd ();
}
Ref: Using Android Assets

I'm not sure it really is an error, but looking at the error, it seems like the path is incorrect. Do you really need to save your file precisely where you're actually saving it ? If not, try this :
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string filename = Path.Combine(path, "myfile.txt");
using (var streamReader = new StreamReader(filename))
{
string json = streamReader.ReadToEnd();
//JObject o1 = JObject.Parse(json);
}
Use this path to save and to load. I'm proceeding like this for all my files and it seems to work well.

This works using Microsoft.Extensions.Configuration.Json
Set json file build action in properties as embedded resource
Project : Client
FileFolder : Configuration
FileName : appsettings.json
JSON :
{
"Rest": {
"Server": "192.168.0.199",
"Port": "5003"
}
}
CODE:
string Namespace = "Client.Configuration";
string FileName = "appsettings.json";
Assembly assembly = GetType().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{Namespace}.{FileName}");
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonStream(stream);
var root = configurationBuilder.Build();
IConfigurationSection restClientConfigration = root.GetSection("Rest");
string server = restClientConfigration.GetSection("Server").Value;
string port = restClientConfigration.GetSection("Port").Value;

Related

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

Get a Json file from a specific folder and serialize it

I need to get json file from a specific folder in my solution. the name of the json file is "plaza.json" and the folder it is in is Data. Please see image below.
How do I get this file and serialize it? I have searched for some answers but the closest is this:
using (var streamReader = new StreamReader("plaza.json"))
{
string json = streamReader.ReadToEnd();
var deserializedObject = JsonConvert.DeserializeObject<SomeClass>(json);
}
if I use that, it doesn't see my json file
using (var streamReader = new StreamReader(Server.MapPath("~/Data/plaza.json"))
{
string json = streamReader.ReadToEnd();
var deserializedObject = JsonConvert.DeserializeObject<SomeClass>(json);
}
This should work, haven’t test but check this how file will be accessed
Depending on you project type it can be server.mappath or hostingenvironment.mappath
If desktop app like win forms or wpf use this
Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Data/plaza.json");
Make sure to put copy file if modified property in build property

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

windows phone 8 resource path at runtime

I have to include some files with my windows phone 8 app. the app will accordingly get those file from resource and read or show partly the content according to the algorithm. how do i get the path to my embedded resource?
If you include file in you project, for instance in Data folder of your project (in our case json file) as a resource then use next code to get content from that file:
string content = string.Empty;
string resource_file = "Data/myfile.json";
if (IsLocalResourceFileExists(resource_file))
{
var resource = Application.GetResourceStream(new Uri(#"/YourProjectName;component/" + resource_file, UriKind.Relative));
StreamReader streamReader = new StreamReader(resource.Stream, System.Text.Encoding.UTF8);
content = streamReader.ReadToEnd();
streamReader.Close();
}
To check if file exist in resource use this:
public bool IsLocalResourceFileExists(string relativePath)
{
return Application.GetResourceStream(new Uri(#"/YourProjectName;component/" + relativePath, UriKind.Relative)) != null;
}
Change YourProjectName to name of you project.
After this, conten holds json file as string.
Hope this help

Categories