如何在 Windows Phone 8.1 中处理预填充的数据库

How to handle prepopulated database in Windows Phone 8.1

我需要在我的 Xamarin.Forms 应用程序中使用预填充的数据库,因此我搜索了可能的解决方案。

我找到了这个 article 并用 Android 进行了测试 - 它工作正常。

但是,它使用 Windows Phone 8 - 与 Windows 8.1 不兼容。

所以我尝试修改这个WindowsPhone8码:

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);
        }
      }
    }
  }
}

进入此代码:

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);

但是,它不起作用,我无法为我现有的数据库文件(它在项目的根目录中)提供正确的文件路径,它总是给我这个错误:

Value does not fall within the expected range.

如何获得预填充文件的正确路径?

此外,当我可以简单地复制文件本身时,为什么我需要使用基于流的 "copy"?

以下代码适用于 Windows Phone 8.1 和 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;
  }
}