I am trying to save a file to the local appdata in a UWP app using Json.
The code creates a file in the folder and then writes the data object to it using Json. Here is the code i use:
StorageFile file = await localstorage.CreateFileAsync("filename.json", CreationCollisionOption.ReplaceExisting)
var filestream = await file.OpenStreamForWriteAsync();
var writer = new StreamWriter(filestream);
var jsonwriter = new JsonTextWriter(writer);
var serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
serializer.Serialize(jsonwriter, DataObject);
Immediately this seems to work and the file seems to be saved successfully, however opening the file manually reveals that it is exactly 16KB and stopped in the middle of an object.
I have been unable to find any mention of a size limitation on any of these objects (streams, StorageFile, Json serializer etc.)
Can anyone explain why the serialization stops at 16KB?
Using the using statement as Romasz suggested and thereby disposing the filestream, writer etc. seems to have fixed my issue.
New code:
StorageFile file = await createFile("filename.json");
using (JsonTextWriter jsonwriter =new JsonTextWriter(new StreamWriter(await file.OpenStreamForWriteAsync())))
{
var serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
serializer.Serialize(jsonwriter, DataObject);
}
Thank you for your answer.
Related
I have below stream which I get from this line where req1 is of HttpResponseMessage type and responseMessage is of type Stream. How can I convert this Stream into a json Object. My end goal is to extract values from the specific keys in this json.
var responseMessage = await req1.Content.ReadAsStreamAsync();
Above answer has a class defined. I didnt want to define different class as my model is dynamic. I found this solution , which worked well and got me the desired result
var serializer = new JsonSerializer();
using (var sr = new StreamReader(responseMessage))
using (var jsonTextReader = new JsonTextReader(sr))
{
var jsObj= serializer.Deserialize(jsonTextReader);
}
try it
// read file into a string and deserialize JSON to a type
Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(#"c:\movie.json"));
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
}
i have a large ObservableCollection that I want to get out as Json file.
I used the following code, But I get an error out of memory
string json = JsonConvert.SerializeObject(content, Formatting.Indented);
await File.WriteAllTextAsync("file.json");
How can I save this huge ObservableCollection in a json file?
Instead of serializing to a string, and then writing the string to a stream, stream it directly:
using var stream = File.Create("file.json");
JsonSerializer.Serialize(stream, content, new JsonSerializerOptions
{
WriteIdented = true
});
try to serialize directly to the file.This way Newtosoft https://www.newtonsoft.com/json/help/html/serializewithjsonserializertofile.htm recomends to do it
using (StreamWriter file = File.CreateText(#"c:\file.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, content);
}
I need to develop a resident app to get info from Win32_BaseBoard class when is required by another app by XML without create any file and then this app must insert or update that information on database.
I saw a few apps but always have to create a file and i don't know if already exists something like that.
The code below will create memory stream with the data instead of writing to a file.
///old code
//XmlSerializer serializer = new XmlSerializer(typeof(AppConfig));
//StreamWriter writer = new StreamWriter(FILENAME);
//serializer.Serialize(writer, config);
//new code
string input = "Your XML here";
string output = "";
XmlSerializer serializer = new XmlSerializer(typeof(AppConfig));
MemoryStream mstream = new MemoryStream(Encoding.UTF8.GetBytes(input));
StreamWriter writer = new StreamWriter(mstream);
serializer.Serialize(writer, config);
I'm trying to save an xml file into a blob. I have no error, everything seems fine except when I navigate to the blob url I see a blank page. If I look at the source code of the web page I can see my xml but truncated.
Here is te code.
StringBuilder fileString = new StringBuilder();
XmlWriterSettings xmlSettings=new XmlWriterSettings
{
Encoding = new UTF8Encoding(false)
};
using (XmlWriter writer = XmlWriter.Create(fileString, xmlSettings))
{
bla bla
}
CloudBlockBlob fileBlob = container.GetBlockBlobReference("site.xml");
fileBlob.UploadText(fileString.ToString());
I found the solution in some other post (not so much the problem although it has to do with encoding of text always being utf-16 despite setting up the writer as utf-8). I am now using a Stream and it works fine.
MemoryStream fileString = new MemoryStream();
XmlWriterSettings xmlSettings=new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Indent = true
};
using (XmlWriter writer = XmlWriter.Create(fileString, xmlSettings))
{
bla bla
}
CloudBlockBlob fileBlob = container.GetBlockBlobReference("site.xml");
fileBlob.UploadText(StreamToString(fileString));
private static string StreamToString(Stream stream)
{
stream.Position = 0;
var reader = new StreamReader(stream);
return reader.ReadToEnd();
}
If you have decided to use a Stream, you can also upload it using UploadFromStream instead of UploadText, which encodes the string into a sequence of bytes, creates a memory stream, and calls UploadFromStream anyway.
I am trying to serialize my Report class info to an XML. At this point I think all of the serialize and deserialize code works, but for the initial write, I'm having trouble performing the serialize, because the XML file doesn't exist yet.
for an empty text file, i can use:
StreamWriter sw = File.CreateText(#"path");
sw.Close();
this is my code block for the serializing. the exception (Directory not found) is getting thrown on the StreamWriter line. I'd like to simply add an if(!File.Exists(xmlPath))...create empty XML. Or maybe there is a more correct way to do this.
public void SerializeToXML(Report newReport)
{
XmlSerializer serializer = new XmlSerializer(typeof(Report));
TextWriter textWriter = new StreamWriter(xmlPath);
serializer.Serialize(textWriter, newReport);
textWriter.Close();
}
The StreamWriter(String) constructor will create the file if it does not already exist:
If the file exists, it is overwritten; otherwise, a new file is created.
However, it will not create any inexistent directories in your path.
DirectoryNotFoundException: The specified path is invalid, such as being on an unmapped drive.
To create any required directories, you can include the following code (at the beginning of your SerializeToXML method):
var dir = Path.GetDirectoryName(xmlPath);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
First to make sure the directory exist you can use:
Directory.CreateDirectory(#"c:\directory\subdirectory");
You don't have to check if directory already exist.
A easy way to convert public classes to XML is to use the following snippet:
public static string ToXml<T>(T obj)
{
using (var ms = new MemoryStream())
using (var sr = new StreamReader(ms))
{
var xmlSer = new XmlSerializer(typeof(T));
xmlSer.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
return sr.ReadToEnd();
}
}
Then you could just use the following code to write it to a file:
var xmlString = Util.ToXml(report);
File.WriteAllText(#"path", xmlString);
(this example is without error handling)
Also, in your code you forgot to close/dispose the TextWriter. I would recommend using the using-statement to handle it for you.
CreateText, and the StreamWriter, will create files if they don't exist, but they won't create directories that don't already exist for you. Is your path correct?
Try Checking with a Directory.Exists(Path.GetDirectoryName(xmlPath)).