MAUI应用通过FTP更新嵌入式SQLite数据库失败问题排查
MAUI嵌入式数据库更新问题解决办法
核心问题分析
- 二进制文件错误用文本流处理:SQLite数据库是二进制格式,你用
StreamReader(文本读取)和StreamWriter(文本写入)处理FTP响应流,会导致二进制数据被错误解析,最终生成空文件或损坏的数据库文件。额外的content.ToUpperInvariant()操作更是完全破坏了数据库结构。 - 路径不一致:版本1.0数据库路径用的是
Environment.SpecialFolder.MyDocuments,版本2.0改用Environment.SpecialFolder.Personal,两者在部分安卓设备上指向的目录不同,导致APP后续读取的不是你刚下载的文件。
修复后的FTP下载代码
public RelayCommand _yesupdate; public RelayCommand YesUpdate => _yesupdate ??= new RelayCommand(() => { // 统一路径,和版本1.0保持一致 string targetFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), ftpInfo.FileName); // 先删除旧文件(如果存在),避免文件残留或覆盖不彻底 if (File.Exists(targetFile)) { File.Delete(targetFile); } // 创建FTP请求 FtpWebRequest request = (FtpWebRequest)WebRequest.Create($"ftp://{ftpInfo.IPV4}/{ftpInfo.FileName}"); request.Method = WebRequestMethods.Ftp.DownloadFile; request.Credentials = new NetworkCredential(ftpInfo.UseName, ftpInfo.Pwd); using FtpWebResponse response = (FtpWebResponse)request.GetResponse(); using Stream responseStream = response.GetResponseStream(); using FileStream outputStream = new FileStream(targetFile, FileMode.Create); // 二进制流直接拷贝,避免文本解析破坏数据 responseStream.CopyTo(outputStream); // 验证文件是否有效(可选,检查文件大小是否合理) if (new FileInfo(targetFile).Length == 0) { Alert.Execute("下载的数据库文件为空,请检查FTP服务器文件"); return; } Alert.Execute("数据库更新完成"); });
额外注意事项
- 流的自动释放:使用
using语句包裹所有流对象,无需手动调用Close(),确保资源正确释放,避免文件被锁定。 - FTP文件验证:下载前确认FTP服务器上的
database.db是完整有效的SQLite数据库,避免源文件本身损坏。 - 安卓权限:在安卓平台上,确保应用拥有读取/写入对应目录的权限,必要时通过MAUI的权限API申请相关权限。
- 数据库连接重置:下载完成后,需要关闭并重新初始化SQLite连接,确保APP读取的是新下载的数据库文件,而不是之前缓存的连接。示例代码:
_connection?.Close(); _connection = null; // 重新初始化连接 var newConnection = Connection;
内容的提问来源于stack exchange,提问作者simone
相关产品推荐
相关产品推荐

