How to create XML file to some folder?
isoStream = new IsolatedStorageFileStream("**Folder/XmlFile.xml**", FileMode.Create, isoStore);
Snatched directly from the Quickstart: Working with files and folders in Windows Phone 8
Check out the section "Creating a folder and writing to a text file"
private async void btnWrite_Click(object sender, RoutedEventArgs e)
{
await WriteToFile();
// Update UI.
this.btnWrite.IsEnabled = false;
this.btnRead.IsEnabled = true;
}
private async Task WriteToFile()
{
// Get the text data from the textbox.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(this.textBox1.Text.ToCharArray());
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("DataFile.txt",
CreationCollisionOption.ReplaceExisting);
// Write the data from the textbox.
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
Below function will save the Jagged array double[][] to the XML. You may use it by modify to your own data type:
private void Save(double[][] m, string filePath)
{
//Open a file stream
System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create);
// Create a xml Serializer object
System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(double[][]));
xmlSer.Serialize(fs, m);
// Close the file stream
fs.Close();
}
Just instead of the double [][] m you should put your own type.
Related
I am using DependencyService in android/ios and windows phone to write and read a XML file in my Xamarin.forms project. I am referring to working with files.
I was able to implement the function given in the example but what I actually want is reading and writing to a XML file.
I followed a usual c# procedure to read and write to xml file but getting errors as the method is async.
I have never used async await methods so not sure how to go about it.
Here is what I tried:
public async Task SaveTextAsync(string filename, string text)
{
ApplicationData data = new ApplicationData();
ApplicationVersion version = new ApplicationVersion();
version.SoftwareVersion = "test";
data.ApplicationVersion = version;
XmlSerializer writer =
new XmlSerializer(typeof(ApplicationData));
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, data);
file.Close();
}
public async Task<string> LoadTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData cars = null;
XmlSerializer serializer = new XmlSerializer(typeof(ApplicationData));
StreamReader reader = new StreamReader(path);
cars = (ApplicationData)serializer.Deserialize(reader);
reader.Close();
}
string CreatePathToFile(string filename)
{
var docsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
return Path.Combine(docsPath, filename);
}
Edit
Working Read and write to txt file code is here:
public async Task SaveTextAsync (string filename, string text)
{
var path = CreatePathToFile (filename);
using (StreamWriter sw = File.CreateText (path))
await sw.WriteAsync(text);
}
public async Task<string> LoadTextAsync (string filename)
{
var path = CreatePathToFile (filename);
using (StreamReader sr = File.OpenText(path))
return await sr.ReadToEndAsync();
}
I managed to get it work. Here is my code:
public async Task SaveTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData data = new ApplicationData();
ApplicationVersion version = new ApplicationVersion();
version.SoftwareVersion = "test version";
data.ApplicationVersion = version;
XmlSerializer writer =
new XmlSerializer(typeof(ApplicationData));
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, data);
file.Close();
}
public async Task<ApplicationData> LoadTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData records = null;
await Task.Run(() =>
{
// Create an instance of the XmlSerializer specifying type and namespace.
XmlSerializer serializer = new XmlSerializer(typeof(ApplicationData));
// A FileStream is needed to read the XML document.
FileStream fs = new FileStream(path, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
// Use the Deserialize method to restore the object's state.
records = (ApplicationData)serializer.Deserialize(reader);
fs.Close();
});
return records;
}
I have got a code from this link:
http://www.codeproject.com/Tips/515704/Archive-Multiple-Files-In-Zip-Extract-Zip-Archive
that compresses and extracts a file in zip format.
However the compressing part in the code just creates an empty zipfile, so how can i add files programmatically in this zip archieve?
i have checked the doc for the ziparchieve class and it has a method for .net called CreateEntryFromFile(String, String) , however this method doesn't apply for .net windows store version.
this is the code we are concerned with:
private async void ZipClick(object sender, RoutedEventArgs e)
{
FileSavePicker picker = new FileSavePicker();
picker.FileTypeChoices.Add("Zip Files (*.zip)", new List<string> { ".zip" });
picker.SuggestedStartLocation = PickerLocationId.Desktop;
picker.SuggestedFileName = "1";
zipFile = await picker.PickSaveFileAsync();
using (var zipStream = await zipFile.OpenStreamForWriteAsync())
{
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create))
{
foreach (var file in storeFile)
{
ZipArchiveEntry entry = zip.CreateEntry(file.Name);
using (Stream ZipFile = entry.Open())
{
byte[] data = await GetByteFromFile(file);
ZipFile.Write(data, 0, data.Length);
}
}
}
}
}
I misunderstood the sample code, it actually can archive the the files you pass it for the first time, but i'm not sure if the same method can be used to add to add other files in the same zip file later.
public async void zipit(StorageFile zipFile, StorageFile file)
{
using (var zipToOpen = await zipFile.OpenStreamForWriteAsync())
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
{
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Name);
using (Stream writer = readmeEntry.Open())
{
//writer.WriteLine("Information about this package.");
//writer.WriteLine("========================");
byte[] data = await GetByteFromFile(file);
writer.Write(data, 0, data.Length);
}
}
}
}
where "zipFile" is the file you have chose to archive in (destination ) and "file" is the original non zipped file.
I am using this code to write into my file:
private async void play_Click(object sender, RoutedEventArgs e)
{
String MyScore;
Double previousScore = 0;
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
var dataFolder1 = await local.CreateFolderAsync("MyFolder", CreationCollisionOption.OpenIfExists);
var file1 = await dataFolder1.CreateFileAsync("MyFile.txt", CreationCollisionOption.OpenIfExists);
var file = await dataFolder1.OpenStreamForReadAsync("MyFile.txt");
using (StreamReader streamReader = new StreamReader(file))
{
MyScore = streamReader.ReadToEnd();
}
if (MyScore != null && !MyScore.Equals(""))
{
previousScore = Convert.ToDouble(MyScore);
}
Double CurerentScore = 0;
Double Total = 0;
String scoreText = this.ScoreTB.Text;
CurerentScore = Convert.ToDouble(scoreText);
Total = previousScore - CurerentScore;
using (var s = await file1.OpenStreamForWriteAsync())
{
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
s.Write(fileBytes, 0, fileBytes.Length);
}
}
But before writing into it, I want that my file should get cleared. What should I do?
This is what i have tried so far but the problem is that it writes the file up to the filebytes.length and due to that if the new information to be writed in file is less in terms of length in comparison to the privous length then some garbage value or unnecessay thing comes after the end of the new file
You can use this snippet :
var folder = ApplicationData.Current.LocalFolder;
// You are going to replace the file
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenStreamForWriteAsync())
{
var content = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
await stream.WriteAsync(content, 0, content.Length);
}
To quote the documentation :
ReplaceExisting : Create the new file or folder with the desired name,
and replaces any file or folder that already exists with that name.
I have clear the file by writing a empty string to it and then i have written what i wanted in my file This solved my issue as nothing was there in the file so whatever i wanted to write to it came up successfully.
Simply use Stream.SetLength like this:
using (var s = await file1.OpenStreamForWriteAsync())
{
// Add this line
s.SetLength(0);
// Then write new bytes. use 's.SetLength(fileBytes.Length)' if needed.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
s.Write(fileBytes, 0, fileBytes.Length);
}
I'm trying to append to a file in the latest Windows Phone. The problem is i'm trying to do everything asynchronously and i'm not sure how to do it.
private async void writeResult(double lat, double lng)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await localFolder.CreateFileAsync("result.txt", CreationCollisionOption.OpenIfExists);
Stream writeStream = await storageFile.OpenStreamForWriteAsync();
using (StreamWriter writer = new StreamWriter(writeStream))
//using (StreamWriter sw = new StreamWriter("result.txt", true))
{
{
await writer.WriteLineAsync(lat + "," + lng);
//await sw.WriteLineAsync(lat + "," + lng);
writer.Close();
//sw.Close();
}
}
}
I have this so far, which writes to the file fine and I can read it later on much the same, however it writes over what I have instead of on a new line. The commented out lines show how to go about without the stream in WP7, but I can't get that to work either (the true is is the append flag) and really should be utilizing the new WP8 methods anyway.
Any comments appreciated
Easier way:
await Windows.Storage.FileIO.AppendTextAsync(storageFile, "Hello");
I used this code, works for me
private async System.Threading.Tasks.Task WriteToFile()
{
// Get the text data from the textbox.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes("Some Data to write\n".ToCharArray());
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("DataFile.txt",
CreationCollisionOption.OpenIfExists);
// Write the data from the textbox.
using (var s = await file.OpenStreamForWriteAsync())
{
s.Seek(0, SeekOrigin.End);
s.Write(fileBytes, 0, fileBytes.Length);
}
}
I was able to use the suggestion ( Stream.Seek() ) by Oleh Nechytailo successfully
I'm having trouble when creating a StreamWriter object in windows-8, usually I just create an instance just passing a string as a parameter, but in Windows 8 I get an error that indicates that it should recieve a Stream, but I noticed that Stream is an abstract class, Does anybody knows how will be the code to write an xml file?, BTW I'm using .xml because I want to save the serialized object, or does anyone knows how to save to a file a serialized object in Windows 8?.
Any ideas?
Currently using Windows 8 Consumer Preview
Code:
StreamWriter sw = new StreamWriter("person.xml");
Error:
The best overloaded method match for 'System.IO.StreamWriter.StreamWriter(System.IO.Stream)' has some invalid arguments
Instead of StreamWriter you would use something like this:
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync();
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
//TODO: Replace "Bytes" with the type you want to write.
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
You can look at the StringIOExtensions class in the WinRTXamlToolkit library for sample use.
EDIT*
While all the above should work - they were written before the FileIO class became available in WinRT, which simplifies most of the common scenarios that the above solution solves since you can now just call await FileIO.WriteTextAsync(file, contents) to write text into file and there are also similar methods to read, write or append strings, bytes, lists of strings or IBuffers.
You can create a common static method which you can use through out application like this
private async Task<T> ReadXml<T>(StorageFile xmldata)
{
XmlSerializer xmlser = new XmlSerializer(typeof(List<myclass>));
T data;
using (var strm = await xmldata.OpenStreamForReadAsync())
{
TextReader Reader = new StreamReader(strm);
data = (T)xmlser.Deserialize(Reader);
}
return data;
}
private async Task writeXml<T>(T Data, StorageFile file)
{
try
{
StringWriter sw = new StringWriter();
XmlSerializer xmlser = new XmlSerializer(typeof(T));
xmlser.Serialize(sw, Data);
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
dataWriter.WriteString(sw.ToString());
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
}
catch (Exception e)
{
throw new NotImplementedException(e.Message.ToString());
}
}
to write xml simply use
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("data.xml",CreationCollisionOption.ReplaceExisting);
await writeXml(Data,file);
and to read xml use
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("data.xml");
Data = await ReadXml<List<myclass>>(file);