将现有数据库(存储文件)复制到存储文件夹

时间:2014-01-10 13:24:41

标签: c# windows-8 windows-store-apps

在我的Windows应用商店应用中,我想将现有数据库复制到存储文件夹 我的数据库放在项目的主文件夹上。

对于复制数据表到存储文件夹,我使用以下代码(link to article):

 StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("people.sqlite");
 await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);

在调试模式下,VS的所有功能都非常出色 但是,如果我使用发布模式或只是停止调试并从Windows打开我的应用程序 - 它不起作用。
也没有例外。尝试拨打CopyAsync时应用只会冻结。我确定,我的databaseFile!=null处于发布模式。

此外,我试图获取这样的文件:

var uri = new Uri("ms-appx:///people.sqlite");
var file = await StorageFile.GetFileFromApplicationUriAsync(uri);

但它并没有解决我的问题。

问题:将现有数据库复制到存储文件夹的正确方法是什么?

更新

谢谢你们的答案,但我无法解决我的问题(

我使用CaliburnMicro实现MVVM。

在我的视图模型中,当我调用页面Loaded时:

private async Task PrepareDatabase()
        {
            bool isDatabaseExisting;
            var storageFolder = ApplicationData.Current.LocalFolder; ;
            try
            {
                await storageFolder.GetFileAsync("database_name.sqlite");
                isDatabaseExisting = true;
            }
            catch
            {
                isDatabaseExisting = false;
            }
            if (!isDatabaseExisting)
            {
                StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("database_name.sqlite");
                await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
            }
        }

我的数据库:
Name - database_name.sqlite;
Build action - Content; Copy to Output Directory - Copy always;

当我从visual studio启动应用程序时 - 所有工作都应该如此。
然后我停止调试,并从Windows运行应用程序 - 当它尝试打开此页面时冻结它。

4 个答案:

答案 0 :(得分:1)

在“Build Action”属性下,您将找到名为“Copy To Output Directory”的属性。确保将其设置为“始终复制”

修改

还有另一种方法可以在项目中包含文件,即嵌入式资源。

在属性中,将Build Action设置为“Embedded Resource”。

using System.Reflection;


public MainPage()
{
  this.InitializeComponent();
  Assembly asm = typeof(MainPage).GetTypeInfo().Assembly;
  Stream stream = asm.GetManifestResourceStream("YourNamespace.filename.extension");


  ConvertToFileAndCopyToLocalDirectory(stream);
}

答案 1 :(得分:1)

虽然我不确定为什么它会在调试中起作用,但我假设您已确保应用程序包清单包含.sqlite文件的声明?

要检查的另一件事是,如果您已在本地文件夹中拥有该名称的数据库。我希望有一个异常但是当我执行我的CopyAsync时,我使用重载来指定文件名和碰撞选项:

await latestFile.CopyAsync(ApplicationData.Current.LocalFolder,
    "My Db Name",
    NameCollisionOption.ReplaceExisting);

编辑:正如Arsalan00所提到的,您可以使用嵌入式资源。我使用以下两个函数复制设置为嵌入资源的数据库来使用它们进行测试:

    private const string DbBasePath = "MyApp.TestHelpers.TestDatabases.";    

    public static IAsyncOperation<IStorageFile> GetDbAsync(string dbName)
    {
        return Util.GetFileFromAssemblyResource(typeof(Data).GetTypeInfo().Assembly, DbBasePath + dbName, dbName, ApplicationData.Current.LocalFolder).AsAsyncOperation();
    }

    public static async Task<IStorageFile> GetFileFromAssemblyResource(Assembly ass, string resource, string filenameToCreate, IStorageFolder location)
    {
        IStorageFile file;
        // read for embedded resources
        using (var stream = ass.GetManifestResourceStream(resource))
        {
            var buf = new byte[stream.Length];
            // create file
            file = await location.CreateFileAsync(DateTime.Now.Ticks + filenameToCreate, CreationCollisionOption.ReplaceExisting);

            using (var memStream = new MemoryStream())
            {
                int read;
                // read bytes at a time from the embedded resource
                while ((read = await stream.ReadAsync(buf, 0, buf.Length)) > 0)
                {
                    // write from memory into buffer
                    await memStream.WriteAsync(buf, 0, read);
                    // write buffer to file
                    await FileIO.WriteBytesAsync(file, buf);
                }
            }
        }
        return file;
    }

答案 2 :(得分:1)

这段代码似乎对我而言。它应该工作。

我只有一个问题: 你可以复制所有的功能,并包括它的调用方式。

我假设你某处缺少一些await / async关键字。

答案 3 :(得分:0)

@jimpanzer我也面临同样的问题,后来发现CopyAsync失败了(当我运行应用程序时,而不是在调试时)因为存在同名文件。这个db文件是从代码创建的,当db文件不是availbale时,该代码用于获取数据。可能你也可能也这样做。干杯