Mono for Android Saving data - c#

I created a homescreen widget, that gets a table of strings from a website. Instead of getting data from web on every update, I want to save the table to the phone and than read from the file on update. I'm using Mono for Android (C#).

Here is a method for saving data to the file system using XML Serialization
public static bool SaveData<T>(Context context, string fileName, T data)
{
try
{
using (Stream stream = context.OpenFileOutput(fileName, FileCreationMode.Private))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
xmlSerializer.Serialize(stream, data);
}
return true;
}
catch (Exception)
{
return false;
}
}
And here is a method for loading serialized data from the file system
public static T LoadData<T>(Context context, string fileName)
{
Java.IO.File file = context.GetFileStreamPath(fileName);
if (file.Exists())
{
using (Stream openStream = context.OpenFileInput(fileName))
{
using (StreamReader reader = new StreamReader(openStream))
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
var loadedObject = serializer.Deserialize(reader);
return (T)loadedObject;
}
catch (Exception ex)
{
// TODO Handle error
return default(T);
}
}
}
}
else
{
throw new Java.IO.FileNotFoundException("Could not find file " + fileName);
}
}
Using these methods you can easily save and load any serializable object such as a string[] you retrieved from the website.
string[] data = { "one", "two", "three" };
JavaIO.SaveData(this, "SavedData.txt", data);
string[] loadedData = JavaIO.LoadData<string[]>(this, "SavedData.txt");

If it's just a simple list, then you can use System.IO.File to load/save text - and you can use something like JSON.Net to convert your list to/from text.
If your data is more incremental, then you can use SQLite instead - try the the SQLite-net ORM wrapper on GitHub

Related

System.IO.FileNotFoundException - cant create XML file in project folder

I am doing a project in C# using Winforms, and I want to create a Podcast RSS reader. So I have a XmlSerializer that saves a podcast entity to a podcastlist and I should then get a podcast.xml file in my project files that it then reads ( I guess). I got it to do exactly that, but with adding Categories. But when I want to read a URL that contains a RSS-file, it wont Save(Serialize) it using the XmlReader. Ive been staring at this for most of the day and I cant just figure out whats going wrong.
Here is my serializer and saved list of Podcasts.
protected string fileOfPodcasts = #"Podcasts.xml";
public List<Podcast> listOfPodcasts = new List<Podcast>();
public void SavePodcastList(List<Podcast> podcastList)
{
XmlSerializer xmlSerializer = new XmlSerializer(podcastList.GetType());
using (FileStream outFile = new FileStream(fileOfPodcasts, FileMode.Create,
FileAccess.Write))
{
xmlSerializer.Serialize(outFile, podcastList);
}
}
public List<Podcast> ReturnPodcasts()
{
List<Podcast> listOfPodcastsToBeReturned;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Podcast>));
using (FileStream inFile = new FileStream(fileOfPodcasts, FileMode.Open,
FileAccess.Read))
{
listOfPodcastsToBeReturned = (List<Podcast>)xmlSerializer.Deserialize(inFile);
}
return listOfPodcastsToBeReturned;
}
public void CreatePodcastObject ( string url, string interval, string category) // 3 parametrar
{
Podcast newPodcast = null;
{
newPodcast = new Podcast(url, interval, category);
}
podcastRepository.Create(newPodcast);
}
public void Create(Podcast entity)
{
podcastList.Add(entity);
SaveChanges();
}

How to read JSON file and display it in console app c#

I have working method for saving data into JSON file.
Now i need to read that file and display in console.
What i'm missing?
Below is my code
My method for reading:
public static void Read(string path, Workspace workspace)
{
using (StreamReader file = new StreamReader(path))
{
try
{
string json = file.ReadToEnd();
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var workspace1 = JsonConvert.DeserializeObject<Workspace>(json, serializerSettings);
workspace = workspace1;
}
catch (Exception)
{
Console.WriteLine("Problem reading file");
}
}
}
In program.cs
Serializer.Save("C:\\Users\\user\\Desktop\\test.json", workspace);
Serializer.Read("C:\\Users\\user\\Desktop\\test.json", workspace);
Console.ReadKey();
On the left is my json file and on the right is what i would like to show in the console.
Correction should be made as follows
public static Workspace Read(string path)
{
using (StreamReader file = new StreamReader(path))
{
try
{
string json = file.ReadToEnd();
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
return JsonConvert.DeserializeObject<Workspace>(json, serializerSettings);
}
catch (Exception)
{
Console.WriteLine("Problem reading file");
return null;
}
}
}
static void Main(string[] args)
{
var data = Read("D:\\workspace.json");
Console.WriteLine("Hello World!");
}
You are missing the keyword ref:
public static void Read(string path, ref Workspace workspace)
That said, you should not use it. Make the function return a Workspace.
This could be little late for the answer. But Reading json became so easy with the new method File.ReadAllText();
String getStrinFromFile = File.ReadAllText("FilePathJson");
Console.WriteLine(getStrinFromFile);

How to pass xml file inside of code instead of a folder path?

I'am trying to not create a file, and pass xml document straight to a SkiaSharp method Load. I mean, is there the way to imitate a path? So here is the code:
public IActionResult svgToPng(string itemId, string mode = "
{
var svgSrc = new XmlDocument();
svgSrc.LoadXml(/*Some xml code*/);
string svgSaveAs = "save file path";
var quality = 100;
var svg = new SkiaSharp.Extended.Svg.SKSvg();
var pict = svg.Load(svgSrc); // HERE, it needs to be a path, not XmlDocument, but i want to pass straight
var dimen = new SkiaSharp.SKSizeI
(
(int) Math.Ceiling(pict.CullRect.Width),
(int) Math.Ceiling(pict.CullRect.Height)
);
var matrix = SKMatrix.MakeScale(1, 1);
var img = SKImage.FromPicture(pict, dimen, matrix);
// Convert to PNG
var skdata = img.Encode(SkiaSharp.SKEncodedImageFormat.Png, quality);
using(var stream = System.IO.File.OpenWrite(svgSaveAs))
{
skdata.SaveTo(stream);
}
ViewData["Content"] = "PNG file was created out of SVG.";
return View();
}
The Load method seems to be this:
public SKPicture Load(
using (var stream = File.OpenRead(filename))
{
return Load(stream);
}
}
look at the code of that library :
https://github.com/mono/SkiaSharp.Extended/blob/master/SkiaSharp.Extended.Svg/source/SkiaSharp.Extended.Svg.Shared/SKSvg.cs
Look at the Load method, it has multiple implementations :
public SKPicture Load(string filename)
{
using (var stream = File.OpenRead(filename))
{
return Load(stream);
}
}
public SKPicture Load(Stream stream)
{
using (var reader = XmlReader.Create(stream, xmlReaderSettings, CreateSvgXmlContext()))
{
return Load(reader);
}
}
public SKPicture Load(XmlReader reader)
{
return Load(XDocument.Load(reader));
}
You will need to pick one of them and use it. Now, nothing stops you from getting the code and adding one extra Load for an XML string for example, but since this is a library you do not control, I'd stick to what you are given.
You could use the XmlReader version, that's probably the closest one to what you want.

An Error occured while parsing EntityName. Line 32, position 51

I've tried looking at several different methods revolving around using XDocument class to load my xml file. However, this error and other variations have been appearing. If I use the absolute path, it displays an error of it cannot find the file.
The issue is my xml file has a combination of both English and Japanese used in it. The link should allow for anyone to view the xml file.
Here is my code and xml file:
public partial class MainWindow : Window
{
private string URLSource = "https://www.dropbox.com/s/nh3bfzvhpj6e3x1/JapanseEnglish.xml?dl=0";
public MainWindow()
{
InitializeComponent();
XMLViewer();
}
private void XMLViewer()
{
try
{
XDocument Doc = XDocument.Load(URLSource);
var Kanji = from WordList in Doc.Descendants("Kanji")
select new
{
Word = WordList.Element("Kanji").Value
};
foreach (var Word in Kanji)
{
JpnTxt.ItemsSource = Word.ToString();
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
The URL you use don't contain a XML document but an HTML page :
https://www.dropbox.com/s/nh3bfzvhpj6e3x1/JapanseEnglish.xml?dl=0
You need to change the value of dl to 1, so Dropbox will return your XML document:
https://www.dropbox.com/s/nh3bfzvhpj6e3x1/JapanseEnglish.xml?dl=1
As #Florian said you should use second link, but maybe you have problem to read unicode xml, so its better using Request and ResponseStream:
private string URLSource = "https://www.dropbox.com/s/nh3bfzvhpj6e3x1/JapanseEnglish.xml?dl=1";
private void XMLViewer()
{
try
{
var request = (HttpWebRequest)WebRequest.Create(URLSource);
var response = (HttpWebResponse)request.GetResponse();
using (var stream = response.GetResponseStream())
{
using (var sr = new StreamReader(stream, true))
{
XDocument Doc = XDocument.Load(sr);
var Kanji = from WordList in Doc.Descendants("Kanji")
select new
{
Word = WordList.Element("Kanji").Value
};
foreach (var Word in Kanji)
{
JpnTxt.ItemsSource = Word.ToString();
}
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

Elency Solutions CSV Library Error C#

I am using the elency solutions CSV library for C# to save and load some data from a file.
My code saves and loads correctly, but when I load and then try to save an error occurs, saying that another process is using the file.
The load method is this:
private void loadfile(string name)
{
int key = 696969;
CsvReader read = new CsvReader("data.csv");
try
{
do
{
read.ReadNextRecord();
} while (name != read.Fields[0]);
int decAgain = int.Parse(read.Fields[1], System.Globalization.NumberStyles.HexNumber); //convert to int
int dec = decAgain ^ key;
MessageBox.Show(dec.ToString());
}
catch (Exception)
{
MessageBox.Show("Not Found");
}
read = null;
}
As you can see, I am sort of disposing the "read" object.
Here is the save method:
private void savefile(string encrypted, string name)
{
CsvFile file = new CsvFile();
CsvRecord rec = new CsvRecord();
CsvWriter write = new CsvWriter();
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
file = null;
rec = null;
write = null;
}
It always gets stuck on append csv.
I do understand the problem. The reader is not being closed successfully. How can I correctly close the file?
NB: I have tried read.Dispose() but it is not working.
Can you please help me out?
Regards
Use using to automatically dispose object. It may solve your issue.
private void savefile(string encrypted, string name)
{
using(CsvFile file = new CsvFile())
{
using(CsvRecord rec = new CsvRecord())
{
using(CsvWriter write = new CsvWriter())
{
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
}
}
}
}

Categories