1

I am trying to figure out how to read and write files in a UWA application. I understand that I need to open a FileStreamm, but I can't figure out how to do that.

I started with this code:

FileStream fs = new FileStream(@"C:\XML\test.txt", FileMode.Create, FileAccess.Write);

seems to work, no red lines.

At the end of all of that I am told to put in Flush and Close, like this:

FileStream fs = new FileStream(@"C:\XML\test.txt", FileMode.Create, 

...

fs.Flush();
fs.Close();

Now, this is where I hit a snag, because fs.Close(); is not even on the list of functions on fs. I just get a red line in my IDE if I try to hardcode it.

Can someone please take the time to help me understand how to do this with UWA? For some reason it seems like there is a different approach in Windows 10 apps, and I have a VERY hard time finding anything that shows me how to do it right. All the tutorials and SOF forum input are about older versions (non-UWA).

When I do this in a console application it all works as expected.

My end goal is to be able to read and write to an XML file in this kind of fashion:

XDocument doc = XDocument.Load(input);
XElement person = doc.Element("Person");
person.Add(new XElement("Employee",
           new XElement("Name", "David"),
           new XElement("Dept", "Chef")));
doc.Save(output);

I'm going down this path because an answer to my previous question told me to use a FileStream, but I simply cannot make that work in UWA.

Sam Hanley
  • 4,707
  • 7
  • 35
  • 63
Hudlommen
  • 89
  • 1
  • 11
  • Did you try the official docs: https://msdn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files it's number 1 in google search, so I dont think you are using the right keyword. Try "uwp read write file". This series https://www.tutorialspoint.com/windows10_development/windows10_development_file_management.htm help alots for me. I think you need to add a file picker, pick the needed file, and read it. – thang2410199 Oct 08 '16 at 17:09
  • Hey hey hey, you pull the google card already? hehe - I think you are right, i didn't come across this article and must have used the wrong keywords. I guess "Fix my life" and "Make it work = true;" just don't cut it these days. – Hudlommen Oct 08 '16 at 17:12
  • I hate the MSDN though, that place is not made for people that don't spend a lot of time programming. How do i make "Windows.Storage.StorageFolder storageFolder =" work, where i choose a specifik folkder? – Hudlommen Oct 08 '16 at 17:22
  • I tried this, with no luck: public async void WriteFile() { StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(@"C:\XML"); StorageFile sampleFile = await folder.GetFileAsync("test.txt"); await FileIO.WriteTextAsync(sampleFile, "Cmoooon!"); } – Hudlommen Oct 08 '16 at 17:30
  • Can someone write a full set of code that can write to "c:\XML\test.txt" in UWA. I simply cannot make it work :S – Hudlommen Oct 08 '16 at 19:35
  • Possible duplicate of [Windows 10 Universal App File/Directory Access](http://stackoverflow.com/questions/33082835/windows-10-universal-app-file-directory-access) – NineBerry Oct 08 '16 at 22:38

2 Answers2

2

You cannot just access any file from a Universal Windows App. Access to the file system is restricted.

See the documentation for details.

To help you further we need to know more about your application. What kind of files do you want to access for what reason?


Example on how to read an Xml File, modify it and store it in an Universal app. You need a button with the following Click handler and a TextBox named "TextBoxLog".

private async void ButtonDemo_Click(object sender, RoutedEventArgs e)
{
     // Get our local storage folder
     var localFolder = ApplicationData.Current.LocalFolder;

     XmlDocument xmlDocument;

     // Try to get file 
     var file = await localFolder.TryGetItemAsync("MyData.xml") as IStorageFile;

     if(file != null)
     {
          // File exists -> Load into XML document
          xmlDocument = await XmlDocument.LoadFromFileAsync(file);
     }
     else
     {
          // File does not exist, create new document in memory
          xmlDocument = new XmlDocument();
          xmlDocument.LoadXml(@"<?xml version=""1.0"" encoding=""UTF-8""?>" + Environment.NewLine + "<root></root>");
     }

     // Now show the current contents
     TextBoxLog.Text = "";

     var lEntries = xmlDocument.GetElementsByTagName("Entry");
     foreach(var lEntry in lEntries)
     {
          TextBoxLog.Text += lEntry.InnerText + Environment.NewLine;
     }

     // Now add a new entry
     var node = xmlDocument.CreateElement("Entry");
     node.InnerText = DateTime.Now.ToString();
     xmlDocument.DocumentElement.AppendChild(node);

     // If the file does not exist yet, create it
     if(file == null)
     {
          file = await localFolder.CreateFileAsync("MyData.xml");
     }

     // Now save the document
     await xmlDocument.SaveToFileAsync(file);

}
NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • Okay, well what i really want is to be able to read and write from a XML file so i can make lists, to use with in the app. – Hudlommen Oct 09 '16 at 01:20
  • But i don't know if i could just make a in-app list that saves the data in between uses with out xml? – Hudlommen Oct 09 '16 at 01:27
  • I guess the reason why i would like to have a XML file, is so i can add data into my app, outside the actual app. So i can access the xml via notepad++, add data that is the usable next time i run the app. – Hudlommen Oct 09 '16 at 02:00
  • You can. Type %localappdata% into the address bar of Windows explorer, then search for "MyData.xml" and you will find the file and can edit it with a normal text editor. – NineBerry Oct 09 '16 at 02:18
  • Yeah iv'e just realized that the UWP apparently is a bit restricted with writing to local files in what ever folder you choose. So you are somewhat (at least what i get now) forced to use their "in app file system" and then just work around it on the outside.. – Hudlommen Oct 09 '16 at 02:32
  • Thank you so much for taking the time. Non of the guides i have found so far have looked like this. I will look into it when i get back up tomorrow, with a clear head. – Hudlommen Oct 09 '16 at 02:35
  • Hurraaa :D i made it work. Now it just need to make sense of it all, but FINALLY i got some text into an xml file :D oh btw, juust in case someone with the lack of skills like me arrives in here. either REMOVE 'Using System.xml' or putin Windows.Data.Xml.Dom. infront of all the xmldocument. – Hudlommen Oct 09 '16 at 02:56
  • 1
    You cant access to whatever file without user's consent. You only have full access to your local sandbox folder for your app. You need to ask user to pick a file using FilePicker to have access to file at other location (but you do have access to some other specific place, but not as freely as your sandbox) – thang2410199 Oct 09 '16 at 15:26
0

Okay, the (simple) solution is to put the xml-file in the PROJECTFOLDER/bin/x86/debug/appX and then write the data to a list this way:

public class dataRaw
    {
        public string data { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
    }

    //You can call this class with x = collectionGenerator.getList() (it returns a list<T>)
    public class collectionGenerator
    {
       public static List<dataRaw> getList()
        {
            //This is the xml file in the folder
            var doc = XDocument.Load("Data.xml"); 

            //This parse the XML and adds in to the list "dataList"
            var dataList = doc.Root
                .Descendants("Person")
                .Select(node => new dataRaw
                {
                    //data, firstName and lastName are in app variables from dataRaw put into listData.
                    //Number, FirstName and LastName are the nodes in the XML file.
                    data = node.Element("Number").Value,
                    firstName = node.Element("FirstName").Value,
                    lastName = node.Element("LastName").Value,
                })
            .ToList();
            return dataList;
        }
    }
Hudlommen
  • 89
  • 1
  • 11