Windows Store (WinRT/Metro) - File Helper Methods


Here are some file helper methods that I’ve put together to speed along dealing with reading and writing basic text and information to the file system in a Metro app. The security model is much tighter in Metro apps which brings more work when dealing with the file system. My initial pass at this was meant to cover reading and writing strings and byte arrays. Metro apps can get to local storage without additional permissions (that is isolated when running Metro) and can get to certain known folders like My Documents, Pictures, etc. when specifically requesting access via the manifest (it’s a little cumbersome in my opinion).

Since I will deal a lot with local storage, most of my methods are centered around those though I have overloads to deal with a StorageFile that you can initialize that goes into one of the other KnownFolders. These are designed to be similar to the Visual Basic “My.Computer.FileSystem.WriteAllText” and “My.Computer.FileSystem.WriteAllBytes” (and the read equivalents) methods.

This is my first pass, these will likely change as I use these in apps, fix bugs and find better ways to handle files.

VB.Net

    Imports Windows.Storage

    Namespace IO
    
        ''' <summary>
        ''' Methods to assist working with files.
        ''' </summary>
        Public Class FileHelpers
            '*********************************************************************************************************************
            '
            '             Class:  FileHelpers
            '      Initial Date:  08/29/2012
            '      Last Updated:  08/31/2012
            '     File Revision:  0
            '     Programmer(s):  Blake Pell (blakepell@hotmail.com, http://www.blakepell.com)
            '
            '*********************************************************************************************************************
    
            ''' <summary>
            ''' A safe storage folder, available to the WinRT application that doesn't need additional manifest permissions
            ''' </summary>
            Enum SafeStorageFolder
                Local
                Roaming
                Temp
            End Enum
    
            ''' <summary>
            ''' Writes all of the text to a specified file in the Local storage.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            Public Shared Async Function WriteAllText(text As String, append As Boolean, fileName As String) As Task
                Await WriteAllText(text, append, fileName, SafeStorageFolder.Local)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in one of the specified safe storage folders.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            Public Shared Async Function WriteAllText(text As String, append As Boolean, fileName As String, safeFolder As SafeStorageFolder) As Task
                Dim folder As Windows.Storage.StorageFolder

                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select

                Dim sf As StorageFile
                If append = True Then
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)
                Else
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting)
                End If

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.AppendTextAsync(sf, text)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in a StorageFolder that has been initialized by the caller.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="folder">The StorageFolder that has been initialized by the caller.  If this is a KnownFolder such as to the users Documents then 
            ''' proper manifest settings will need to be in place for this to execute.</param>
            Public Shared Async Function WriteAllText(text As String, append As Boolean, fileName As String, folder As StorageFolder) As Task
                Dim sf As StorageFile

                If append = True Then
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)
                Else
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting)
                End If

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.AppendTextAsync(sf, text)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in the local storage folder.
            ''' </summary>
            ''' <param name="b">The byte array to write.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            Public Shared Async Function WriteAllBytes(b() As Byte, fileName As String) As Task
                Await WriteAllBytes(b, fileName, SafeStorageFolder.Local)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in one of the specified safe storage folders.
            ''' </summary>
            ''' <param name="b">The byte array to write.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            Public Shared Async Function WriteAllBytes(b() As Byte, fileName As String, safeFolder As SafeStorageFolder) As Task
                Dim folder As Windows.Storage.StorageFolder

                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select

                Dim sf As StorageFile
                sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.WriteBytesAsync(sf, b)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in one of the specified safe storage folders.
            ''' </summary>
            ''' <param name="b">The byte array to write.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="folder">The StorageFolder that has been initialized by the caller.  If this is a KnownFolder such as to the users Documents then 
            ''' proper manifest settings will need to be in place for this to execute.</param>
            Public Shared Async Function WriteAllBytes(b() As Byte, fileName As String, folder As StorageFolder) As Task
                Dim sf As StorageFile
                sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.WriteBytesAsync(sf, b)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to a specified file in the Local storage.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            Public Shared Async Function WriteAllLines(text As IEnumerable(Of String), append As Boolean, fileName As String) As Task
                Await WriteAllLines(text, append, fileName, SafeStorageFolder.Local)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in one of the specified safe storage folders.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            Public Shared Async Function WriteAllLines(text As IEnumerable(Of String), append As Boolean, fileName As String, safeFolder As SafeStorageFolder) As Task
                Dim folder As Windows.Storage.StorageFolder
                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select
                Dim sf As StorageFile
                If append = True Then
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)
                Else
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting)
                End If

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.AppendLinesAsync(sf, text)
            End Function
    
            ''' <summary>
            ''' Writes all of the text to the specified file in a StorageFolder that has been initialized by the caller.
            ''' </summary>
            ''' <param name="text">The text to write.</param>
            ''' <param name="append">Whether or not to append the data or overwrite what is in the file.</param>
            ''' <param name="fileName">The name of the file to write the data to.</param>
            ''' <param name="folder">The StorageFolder that has been initialized by the caller.  If this is a KnownFolder such as to the users Documents then 
            ''' proper manifest settings will need to be in place for this to execute.</param>
            Public Shared Async Function WriteAllLines(text As IEnumerable(Of String), append As Boolean, fileName As String, folder As StorageFolder) As Task
                Dim sf As StorageFile
                If append = True Then
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists)
                Else
                    sf = Await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting)
                End If

                ' WriteTextAsync will always overwrite the file even if the existing file has been opened.  We'll use
                ' AppendTextAsync here, the above CreateFileAsync will handle whether the file has been truncated or not.
                Await FileIO.AppendLinesAsync(sf, text)
            End Function
    
            ''' <summary>
            ''' Reads all of the text in as a string from the specified file in the local storage folder.
            ''' </summary>
            ''' <param name="fileName">The name of the file to read all of the text from.</param>
            Public Shared Async Function ReadAllText(fileName As String) As Task(Of String)
                Return Await ReadAllText(fileName, SafeStorageFolder.Local)
            End Function
    
            ''' <summary>
            ''' Reads all of the text in as a string from the specified file in one of the safe storage folders.
            ''' </summary>
            ''' <param name="fileName">The name of the file to read all of the text from.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            Public Shared Async Function ReadAllText(fileName As String, safeFolder As SafeStorageFolder) As Task(Of String)
                Dim folder As Windows.Storage.StorageFolder
                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select

                Dim sf As StorageFile
                sf = Await folder.GetFileAsync(fileName)
                Return Await FileIO.ReadTextAsync(sf)
            End Function
    
            ''' <summary>
            ''' Reads all of the text in as a string from the specified file in one of the safe storage folders.
            ''' </summary>
            ''' <param name="fileName">The name of the file to open and read.</param>
            ''' <param name="folder">The StorageFolder that has been initialized by the caller.  If this is a KnownFolder such as to the users Documents then 
            ''' proper manifest settings will need to be in place for this to execute.</param>
            Public Shared Async Function ReadAllText(fileName As String, folder As StorageFolder) As Task(Of String)
                Dim sf As StorageFile
                sf = Await folder.GetFileAsync(fileName)
                Return Await FileIO.ReadTextAsync(sf)
            End Function
    
            ''' <summary>
            ''' Deletes the specified file from the safe folder.
            ''' </summary>
            ''' <param name="fileName">The name of the file to delete.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            Public Shared Async Function DeleteFile(fileName As String, safeFolder As SafeStorageFolder) As Task
                Dim folder As Windows.Storage.StorageFolder
                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select
                Await folder.DeleteAsync(StorageDeleteOption.PermanentDelete)
            End Function
    
            ''' <summary>
            ''' Deletes the specified file from the safe folder.
            ''' </summary>
            ''' <param name="fileName">The name of the file to delete.</param>
            ''' <param name="newName">The name that you want the file to be renamed to.</param>
            ''' <param name="safeFolder">The safe storage folder that should be written to.  These folders are isolated for the application to use
            ''' and do not require additional manifest permissions.</param>
            ''' <param name="overwrite">Whether or not the destination file should be overwritten if a file of the same name exists.  If this value
            ''' is false and the filename already exists an exception will be generated.</param>
            Public Shared Async Function RenameFile(fileName As String, newName As String, safeFolder As SafeStorageFolder, overwrite As Boolean) As Task
                Dim folder As Windows.Storage.StorageFolder
                Select Case safeFolder
                    Case SafeStorageFolder.Local
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                    Case SafeStorageFolder.Roaming
                        folder = Windows.Storage.ApplicationData.Current.RoamingFolder
                    Case SafeStorageFolder.Temp
                        folder = Windows.Storage.ApplicationData.Current.TemporaryFolder
                    Case Else
                        folder = Windows.Storage.ApplicationData.Current.LocalFolder
                End Select
                If overwrite = True Then
                    Await folder.RenameAsync(newName, NameCollisionOption.ReplaceExisting)
                Else
                    Await folder.RenameAsync(newName, NameCollisionOption.FailIfExists)
                End If
            End Function
    
        End Class
    
    End Namespace

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.