Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 663|回复: 0

.Net版SQLite无法访问网络位置的数据库文件-winOpen,os_win.c 36702异常

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-22 04:09:13 | 显示全部楼层 |阅读模式

    最近一个C#小程序,希望将SQLite数据库放在网络共享的位置,让多个客户端同时访问。却发现SQLite连接不上该网络位置的数据库,而如果数据库在本地则一切正常。

    例如将SQLite数据库 test.dat 放在共享位置:\\System\Data\test.dat
    通过SQLite创建数据库连接,执行Open时,将抛掷异常:

    SQLite error (14): os_win.c:36702: (3) winOpen(D:\System\Data\test.dat) - 系统找不到指定的路径。
    SQLite error (14): os_win.c:36702: (3) winOpen(D:\System\Data\test.dat) - 系统找不到指定的路径。
    SQLite error (14): cannot open file at line 36711 of [9491ba7d73]
    “System.Data.SQLite.SQLiteException”类型的第一次机会异常在 System.Data.SQLite.dll 中发生
    System.Data.SQLite.SQLiteException (0x80004005): unable to open database file
       在 System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
       在 System.Data.SQLite.SQLiteConnection.Open()
       在 MyMemory.Frame.DAL.SQLiteRunner..ctor(String connectionString) 位置 d:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\SQLiteRunner.cs:行号 34
       在 MyMemory.Frame.DAL.DatabaseServices.CreateConnection() 位置 d:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\DatabaseServices.cs:行号 23
       在 MyMemory.Frame.DAL.DatabaseServices.Initialize(String dataDir) 位置 d:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\DatabaseServices.cs:行号 54
    “System.Data.SQLite.SQLiteException”类型的第一次机会异常在 MyMemory.Frame.dll 中发生
    System.Data.SQLite.SQLiteException (0x80004005): unable to open database file
       在 System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
       在 System.Data.SQLite.SQLiteConnection.Open()
       ...

    即传入的SQLite网络共享路径(以\\开头)在SQLite内部某个环节被转换成为了本地路径!

    问题处在SQLite提供的程序集内,那么SQLite最新版本是否已经修复这个问题了(或是从某版故意为之,不让访问网络共享位置的文件了呢)?
    到官网http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki下载最新版本( System.Data.SQLite 1.0.94.0 (3.8.6) )替换后重试,还是出现上面的异常。

    好吧,既然是开源的,那就下载源代码,看看是什么原因。

    下载了之后,采用VS编译,通过解决方案中自带的Test项目,可以输入数据库链接:

    点击Run就可以进入断点调试了。

    废话少说,直接上结果:

    Open过程问题点的方法调用过程如下

    \sqlite-netFx-source-1.0.94.1\System.Data.SQLite\SQLiteConnection.cs Line 2372
    SortedList<string, string> opts = ParseConnectionString(
              _connectionString, _parseViaFramework);

    \sqlite-netFx-source-1.0.94.1\System.Data.SQLite\SQLiteConnection.cs Line 1875
    arParts = SQLiteConvert.NewSplit(s, ';', true, ref error);

    \sqlite-netFx-source-1.0.94.1\System.Data.SQLite\SQLiteConvert.cs Line 716
    if ((character != EscapeChar) &&
                        (character != QuoteChar) &&
                        (character != separator))

    将上面的if ( //(character != EscapeChar) && 注释掉后半行(注意:不推荐这种注释代码的方法)
                        (character != QuoteChar) &&
                        (character != separator))

    再编译,重新执行Test.exe 一切OK。

    至于为什么有这个限制,源代码中的注释是:

                    // --Line 709
                    // HACK: Only consider the escape character to be an actual
                    //       "escape" if it is followed by a reserved character;
                    //       otherwise, emit the original escape character and
                    //       the current character in an effort to help preserve
                    //       the original string content.
                    // --Line 715

    官方文档说,放在网络位置共享访问的SQLite数据库,在某些特定情况下容易损坏。看来这个问题大神们解决不好,准备干脆屏蔽掉这种使用方式了。

    提醒一下,SQLite源码默认用的.Net Framework 4.5,编译时注意切换为项目需要的.Net Framework版本。

    最后提供修改后的System.Data.SQLite.dll .Net Framework 4.0版:
    下载

    转载请注明出处:原文http://www.cnblogs.com/yangzhj/p/4230123.html

    (全文完)

    -------------------------------------------
    2015-01-17 10:45 PS:

    发现之前提供的下载库x86版本编译有些问题。现已重新编译,且SQLite.Interop.dll均编译为静态链接,方便迁移使用。谢谢。


     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 03:49 , Processed in 0.059328 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表