I need to use a prepopulated database in my Xamarin.Forms application, so I searched for possible solutions.
I've found this article and tested with Android - it worked okay.
However, it uses Windows Phone 8 - that is not compatible with Windows 8.1.
So I tried to modify this Windows Phone 8 code:
public static void CopyDatabaseIfNotExists(string dbPath)
{
var storageFile = IsolatedStorageFile.GetUserStoreForApplication();
if (!storageFile.FileExists(dbPath))
{
using (var resourceStream = Application.GetResourceStream(new Uri("people.db3", UriKind.Relative)).Stream)
{
using (var fileStream = storageFile.CreateFile(dbPath))
{
byte[] readBuffer = new byte[4096];
int bytes = -1;
while ((bytes = resourceStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
fileStream.Write(readBuffer, 0, bytes);
}
}
}
}
}
Into this code:
public static async void CopyDatabaseIfNotExists(string dbPath)
{
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFile existingFile = await Windows.Storage.StorageFile.GetFileFromPathAsync("prep.db");
IStorageFile storageFile = await applicationFolder.GetFileAsync(dbPath);
if (storageFile == null)
{
await existingFile.CopyAndReplaceAsync(storageFile);
However, it does not work, I can't provide a proper filepath for my existing db file (it is in the root of the project), it always gives me this error:
Value does not fall within the expected range.
How could I get a proper path to my prepopulated file?
Also, why do I need to use a stream based "copy" when I could simply copy the file itself?
The following code works for Windows Phone 8.1 and UWP:
public async void CopyDatabaseIfNotExists(string dbPath)
{
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
var existingFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(myDBFileName);
if (!await CheckForExistingFile(myDBFileName))
await existingFile.CopyAsync(applicationFolder);
}
private async Task<bool> CheckForExistingFile(string filePath)
{
try
{
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(Uri.EscapeDataString(filePath));
//no exception means file exists
return true;
}
catch (FileNotFoundException ex)
{
//find out through exception
return false;
}
}