【问题标题】:Zip file extraction when restoring a database还原数据库时提取 Zip 文件
【发布时间】:2018-10-03 09:49:31
【问题描述】:

我已经为我的应用程序创建了一个备份和恢复过程。运行备份时,它将在与数据库相同的目录中创建 SQLite 数据库的 .zip 文件。

恢复数据库时,会重命名数据库,将其从EPOSDatabase.db3改为tempEPOS.db3

然后,在删除重命名的临时数据库之前,它会获取选定的文件并将其提取到同一位置,名称为 EPOSDatabase.db3

string dbPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

if (File.Exists(dbPath + "/tempEPOS.db3"))
  {
    File.Delete(dbPath + "/tempEPOS.db3");
  };

  File.Move(dbPath + "/EPOSDatabase.db3", dbPath + "/tempEPOS.db3");

  ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath + "/EPOSDatabase.db3");

  File.Delete(dbPath + "/tempEPOS.db3");

我的问题是当我有打开连接的代码时,例如当我在执行还原后打开系统设置页面时,我收到一个错误:

“无法打开数据库文件:/data/user/0/com.companyname.ACPlus_MobileEPOS/files/EPOSDatabase.db3 (CannotOpen)”

作为进一步的调试测试,我将这段代码添加到应用程序的启动中:

string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

foreach (var file in Directory.GetFiles(path))
{
   string strFile = Convert.ToString(file);
}

public readonly string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "EPOSDatabase.db3");

var db = new SQLiteConnection(dbPath);
db.CreateTable<Category>();
db.CreateTable<SystemSettings>();

db.Close();

在 foreach 循环中,它只找到了我试图从中恢复的原始 .zip 文件。

然后当它到达线时 var db = new SQLiteConnection(dbPath);

使用消息创建数据库失败

“无法打开数据库文件:/data/user/0/com.companyname.ACPlus_MobileEPOS/files/EPOSDatabase.db3”

文件似乎不存在,所以没有正确提取,但如果是这种情况,为什么它不只是创建一个新数据库,而不是尝试打开它?

【问题讨论】:

  • 重新检查您的提取逻辑
  • @Nkosi 我看不出逻辑错在哪里?在重命名当前数据库之前,它会检查任何未删除的旧重命名数据库。然后,在删除旧版本之前,它将 .zip 文件提取到与数据库路径使用的目录和名称相同的目录 - 我错过了什么?
  • 特别是ExtractToDirectory。您正在将 zip 文件的内容解压缩到名为 EPOSDatabase.db3目录。您是否真的查看了该位置以了解由于代码而发生的情况?

标签: c# sqlite xamarin


【解决方案1】:

提取逻辑需要重新检查。

特别是ExtractToDirectory

将指定 zip 存档中的所有文件解压缩到文件系统上的一个目录中。

public static void ExtractToDirectory (string sourceArchiveFileName, string destinationDirectoryName);

在原代码中

ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath + "/EPOSDatabase.db3");

压缩文件的内容被解压到一个名为{path}/EPOSDatabase.db3/目录

如果目标只是从存档中提取到目录,则只需要目录位置。

ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath);

此外,在删除旧文件之前,应检查以确保所需文件在还原后确实存在。

//... extraction code omitted for brevity

if (!File.Exists(dbPath + "/EPOSDatabase.db3")) {
    //...either throw error or alert that database is not present

    //...could consider return old file back to original sate (optional)
} else {
    File.Delete(dbPath + "/tempEPOS.db3");
}

【讨论】:

  • 是的,我在重新阅读文档后意识到您指的是什么。有趣的是,它现在确实打开了连接,所以这个问题已经解决,它现在无法从 SystemSettings 表中读取,声称它不存在。这根本不应该改变数据库,不是吗?
  • 进一步检查以确保备份一开始就正确完成。如果还原没有表,则它不在原始备份中。
  • 哦,看来是因为我在CreateFromDirectory 方法的startPath 中包含了文件名。但是,如果我删除它,它将备份整个文件夹而不仅仅是数据库。如何只压缩单个文件而不是整个文件夹?
  • 创建一个 ZipArchive 并单独添加特定文件。您打开文件的流并将其传递给存档。这里有很多答案展示了如何做到这一点。
猜你喜欢
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多