通过System.Data.SQLite支持长unicode文件路径

通过System.Data.SQLite支持长unicode文件路径,sqlite,unicode,system.data.sqlite,Sqlite,Unicode,System.data.sqlite,我正在开发一个应用程序,它需要能够以用户定义的路径创建和操作SQLite数据库。我遇到了一个我不太明白的问题。我正在用一些非常粗略的样本数据测试我的东西,这些数据具有巨大而笨拙的unicode路径,对于大多数人来说没有问题,但对于其中一个来说有问题 工作连接字符串的一个示例是: Data Source="c:\test6\意外な高価で売れるかも? 出品は手順を覚えれば後はかんたん!\11オークションストアの出品は対象外とさせていただきます。\test.db";Version=3; 而失败的是

我正在开发一个应用程序,它需要能够以用户定义的路径创建和操作SQLite数据库。我遇到了一个我不太明白的问题。我正在用一些非常粗略的样本数据测试我的东西,这些数据具有巨大而笨拙的unicode路径,对于大多数人来说没有问题,但对于其中一个来说有问题

工作连接字符串的一个示例是:

Data Source="c:\test6\意外な高価で売れるかも? 出品は手順を覚えれば後はかんたん!\11オークションストアの出品は対象外とさせていただきます。\test.db";Version=3;
而失败的是

Data Source="c:\test6\意外な高価で売れるかも? 出品は手順を覚えれば後はかんたん!\22今やPCライフに欠かせないのがセキュリティソフト。そのため、現在何種類も発売されているが、それぞれ似\test.db";Version=3;
由于我无法控制的原因,我正在使用System.Data.SQLite v1.0.66.0,但我很快用最新的v1.0.77.0进行了测试,并遇到了同样的问题

无论是在尝试新建test.db文件时,还是在我手动将一个文件放入其中并尝试打开时,SQLiteConnection.open都会抛出一个异常,仅表示“无法打开数据库文件”,堆栈跟踪显示抛出的实际上是System.Data.SQLite.SQLite3.open

有没有办法让System.Data.SQLite很好地使用这些路径?一种解决方法是在临时位置创建和操作数据库,然后将它们移动到实际存储位置,因为我通常可以创建和操作文件。不过这是最后的办法


谢谢。

我猜您使用的是日文语言环境机器,默认系统编码(ANSI代码页)是cp932日文(≈轮班(JIS)

第二条路径包含:

它编码为字节序列:

0x83 0x5C
Shift-JIS是一种多字节编码,其不幸的特性是有时会在尾字节中重复使用ASCII码单元。在这种情况下,它使用了对应于反斜杠
\
的字节0x5C。(由于历史原因,这通常以日文字体显示为日元符号。)

因此,如果将此路径名传递到基于字节的API中,它将在ANSI代码页中进行编码,并且您将无法分辨反斜杠作为目录分隔符与多字节编码的副作用之间的区别。因此,当使用基于字节的IO方法访问时,中包含以下字符之一的任何路径都将失败:

―ソЫⅨ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃畚秉綵臀藹觸軆鐔饅鷭偆砡纊犾
(此外,任何包含cp932中不存在的Unicode字符的路径名都将自然失败。)

在幕后,SQLite似乎正在使用基于字节的IO方法来打开给定的文件名。这是不幸的,但在跨平台代码中非常常见,因为POSIX C标准库被定义为使用基于字节的文件名来执行诸如file
open()
之类的操作

因此,使用C stdlib函数不可能可靠地访问具有非ASCII名称的文件。这种可悲的情况继承到使用stdlib编写的各种跨平台库和语言中;只有特定支持Win32 Unicode文件名(如Python)的工具才能可靠地访问Windows下的所有文件

那么,你的选择是:

  • 根据移动/重命名建议,避免在数据库的路径名中使用非ASCII字符

  • 继续依赖日语的系统语言环境(ANSI代码页=932),只需重命名文件以避免上面列出的任何字符

  • 获取相关文件的短(8.3)文件名,并使用该文件名代替真实文件名,例如
    c:\test6\85D0~1\22PC~1\test.db
    。您可以使用
    dir/x
    查看短文件名。它们总是纯ASCII码,避免了编码问题

  • 添加一些代码,使用GetShortPathName从实际文件名中获取短文件名。这是一个Win32 API,所以您需要从.NET调用它。注:如果在禁用短文件名生成功能的机器上运行,短文件名仍将失败

  • 说服SQLite添加对Windows Unicode文件名的支持

  • 说服微软一劳永逸地解决这个问题,像在所有其他现代操作系统上一样,对字节接口UTF-8进行默认编码