为什么自己的NDK/JNI工程编译的Sqlite3,打开2G以上数据文件的结果不正确?

huangbeyond 2018-08-14 02:46:12
环境:Eclipse,NDK/JNI,Sqlite3.24.0源码
原因:因公司项目需要在Android上访问Sqlite3数据文件,所以在NDK工程中直接加入Sqlite3源码编译出.so文件。并用JNI封装相应的接口类供JAVA调用。

现象1:对小于2G的Sqlite3数据文件(在PC上生成并严格测试后,再拷贝到Android手机的机身存储)进行“增删改查”,一切正常。对大于2G的Sqlite3数据文件进行“增删改查”,则操作会部分失败。
现象2:以2G为分界线,存储在2G范围之内的数据,正确查询;查询超出2G范围的数据,查询出错

对大于2G的Sqlite3数据文件:
排查1:一开始以为是Sqlite3对超过2G文件的支持性问题,但通过阅读并跟踪Sqlite3源码,基本能排除这个原因,因为Sqlite3的源码编写得非常规范严谨,已经内置支持对Android-大文件的支持。(见Sqlite3源码“lseek”关键字所处的注释);
排查2:在相同的手机环境下,用JAVA代码调用系统自带的Sqlite3类来操作该“大于2G的Sqlite3数据文件”,则操作正常。且:手机自带的Sqlite3版本比我用NDK编译的版本还要低,显然不是Sqlite3源码版本问题;

问题:为什么自己在工程中编译的Sqlite3,不能正确操作超过2G的数据库文件?

哪位同行也遇过类似问题,望不吝指教!!!


补充说明:
1、考虑性能问题,项目是用NDK/C++来开发核心引擎,封装出JNI类供JAVA业务代码调用,所以肯定不能使用Android自带的Sqlite3库;
2、封装出的.so文件,操作2G以内的数据库,已通过多个项目实践,没有任何问题;




...全文
405 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangbeyond 2018-08-16
  • 打赏
  • 举报
回复
问题解决了。

结论:所谓“超过2G就无法打开的问题“,是错觉。真正原因是:大量数据的数据文件在查询时,一般会引发Sqlite3自身创建临时文件来建立缓冲机制。而Android系统因为权限控制的因素,导致Sqlite3在临时目录下创建文件失败。所以形成“超过2G就打开失败”的错觉。

当我跟踪到Sqlite3源码的unixTempFileDir时,发现它是返回失败的根源,于是百度了这个关键词,找到了正解。

https://blog.csdn.net/lyyuan01/article/details/72628081

这位同行的现象与我完全一致,于是按照他的方法顺利解决了问题。向他致敬!
assky124 2018-08-15
  • 打赏
  • 举报
回复
分库存怎么样。

会不会是编译成32位版本的问题,32位单进程不能超过2G,或许Android上也存在这样的问题。还有文件格式
huangbeyond 2018-08-15
  • 打赏
  • 举报
回复
引用 2 楼 assky124 的回复:
分库存怎么样。

会不会是编译成32位版本的问题,32位单进程不能超过2G,或许Android上也存在这样的问题。还有文件格式


感谢关注!

1、分库(即:分多文件)存,理论上可以解决问题,但会带来很多额外的开发改造工作,现阶段进度比较吃紧,不敢大改;

2、我也曾怀疑是NDK编译为32位导致的,但从Sqlite3的源码来看,它的32位版也应该能支持大文件的。至少,Windows下编译出的32位Sqlite3,对大文件支持是没有任何问题的。文件格式应该是没有问题的,都是在Windows下验证过拷贝过去的。
huangbeyond 2018-08-14
  • 打赏
  • 举报
回复
自己的问题,自己顶一下

80,330

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧