Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly read and write a file using Windows.Storage on Windows Phone 8

I'm needing to just simply write to a file and read from a file in Windows Phone 8 using the Windows.Storage APIs. This is relatively easy using the old IsolatedStorage method, but it's proving significantly harder using the new WinRT API.

I've been trying to write it, but there seem to be all these weird things like IBuffer. and such. Using the full version of WinRT, it's quite easy using Windows.Storage.FileIO which appears to exist to keep developers like me from going insane. However, it's not implemented in the Phone version. Also, I watched a Channel9 video which showed some code samples, but they had a mistake in that they used methods marked Security Critical to get regular streams. Apparently getting a regular Stream just isn't allowed.

So, can someone provide me with a concise and correct snippet on how to just read a file into a string and how to write a string to a file, complete with proper using and disposal techniques?

like image 830
Earlz Avatar asked Dec 04 '22 11:12

Earlz


2 Answers

Here's a simple example:

public async Task WriteDataToFileAsync(string fileName, string content)
{
    byte[] data = Encoding.Unicode.GetBytes(content);

    var folder = ApplicationData.Current.LocalFolder;
    var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

    using (var s = await file.OpenStreamForWriteAsync())
    {
        await s.WriteAsync(data, 0, data.Length);
    }
}

public async Task<string> ReadFileContentsAsync(string fileName)
{
    var folder = ApplicationData.Current.LocalFolder;

    try
    {
        var file = await folder.OpenStreamForReadAsync(fileName);

        using (var streamReader = new StreamReader(file))
        {
            return streamReader.ReadToEnd();
        }
    }
    catch (Exception)
    {
        return string.Empty;
    }
}

use them like this:

await this.WriteDataToFileAsync("afile.txt", "some text to save in a file");

var contents = await this.ReadFileContentsAsync("afile.txt");
like image 184
Matt Lacey Avatar answered Jan 19 '23 00:01

Matt Lacey


I haven't tried that with Windows Phone 8, but here's what WinRT XAML Toolkit has for Windows 8 that could work.



using System;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

namespace WinRTXamlToolkit.IO.Extensions
{
    /// <summary>
    /// Extensions for simple writing and reading of strings to/from files.
    /// </summary>
    /// <remarks>
    /// Note that these were created before FileIO class existed in WinRT, but they still serve a purpose.
    /// </remarks>
    public static class StringIOExtensions
    {
        /// <summary>
        /// Reads a string from a text file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="folder">The folder.</param>
        /// <returns></returns>
        public static async Task<string> ReadFromFile(
            string fileName,
            StorageFolder folder = null)
        {
            folder = folder ?? ApplicationData.Current.LocalFolder;
            var file = await folder.GetFileAsync(fileName);

            using (var fs = await file.OpenAsync(FileAccessMode.Read))
            {
                using (var inStream = fs.GetInputStreamAt(0))
                {
                    using (var reader = new DataReader(inStream))
                    {
                        await reader.LoadAsync((uint)fs.Size);
                        string data = reader.ReadString((uint)fs.Size);
                        reader.DetachStream();

                        return data;
                    }
                }
            }
        }

        /// <summary>
        /// Writes a string to a text file.
        /// </summary>
        /// <param name="text">The text to write.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="folder">The folder.</param>
        /// <param name="options">
        /// The enum value that determines how responds if the fileName is the same
        /// as the name of an existing file in the current folder. Defaults to ReplaceExisting.
        /// </param>
        /// <returns></returns>
        public static async Task WriteToFile(
            this string text,
            string fileName,
            StorageFolder folder = null,
            CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
        {
            folder = folder ?? ApplicationData.Current.LocalFolder;
            var file = await folder.CreateFileAsync(
                fileName,
                options);
            using (var fs = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                using (var outStream = fs.GetOutputStreamAt(0))
                {
                    using (var dataWriter = new DataWriter(outStream))
                    {
                        if (text != null)
                            dataWriter.WriteString(text);

                        await dataWriter.StoreAsync();
                        dataWriter.DetachStream();
                    }

                    await outStream.FlushAsync();
                }
            }
        }
    }
}
like image 39
Filip Skakun Avatar answered Jan 18 '23 23:01

Filip Skakun