请选择 进入手机版 | 继续访问电脑版
Ptlogin
 找回密码
 立即注册

android.database.sqlite.SQLiteFullException:database or disk is full (code 13)

[复制链接]
  • TA的每日心情
    开心
    2016-2-3 18:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    107

    主题

    948

    帖子

    3390

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    3390
    发表于 2016-5-17 17:53:20
    出错堆栈# d4 ~9 I; }7 X& x1 _
    [Java] 纯文本查看 复制代码
    android.database.sqlite.SQLiteFullException 
    database or disk is full (code 13)
    android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) 
    android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782) 
    android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788) 
    android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) 
    android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469) 
    xxx.xxx.buglyshare.MainActivity$1.onClick(MainActivity.java:40) 
    android.view.View.performClick(View.java:4448) 
    android.view.View$PerformClick.run(View.java:18461) 
    android.os.Handler.handleCallback(Handler.java:733) 
    android.os.Handler.dispatchMessage(Handler.java:95) 
    android.os.Looper.loop(Looper.java:136) 
    android.app.ActivityThread.main(ActivityThread.java:5072) 
    java.lang.reflect.Method.invokeNative(Native Method) 
    java.lang.reflect.Method.invoke(Method.java:515) 
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 
    dalvik.system.NativeStart.main(Native Method)   
    

    0 j; m$ V+ H( f1 Z3 S* P7 A+ g6 r* k3 t0 F5 G0 P7 c3 q9 n; ~
    【出错代码】
    2 [" C% |9 P; V5 l& W; a- G
    类:me.bfbrmt.bugly2.MainActivity
    22.png , z4 f" T. u9 [, j( p% @
    ; D7 w4 C2 K! }, q) ^4 M' t
    代码片段(第40行):  v' Q9 i2 [! y8 B( u3 i

    ; W8 {  {1 F& k/ D/ ]! e% F【出错原因】/ e# V0 ^$ s0 s# d; c2 {
    从异常的完整描述:
    “android.database.sqlite.SQLiteFullException: database or disk is full (code 13)”
    很容易看出,这是因为数据库的体积达到最大限制或者磁盘已满。也就是说数据量太大,或者磁盘空间不足。
    " B' Z8 H; I4 F
    分析:
    注意第 24 行的语句“database.setMaximumSize(100000);”。setMaximumSize 方法的功能是设置数据库的最大容量,以字节数计。(需要注意的是,最终数据库的大小可能略大于此值,随后会进行分析。不过这不影响此处的分析,因为不会大太多。)
    接着在第 31 ~ 39 行,向数据库写入大量数据(显然大大超过 100000 字节),从而导致此异常的发生。
    出错猜测:
    1. 数据库数据量超过限制;
    一般地,我们不会去设定数据库的最大容量。在默认情况下,数据库容量是一个很大的值。以我测试用的手机为例,第 24 行获取的是默认容量。第 25 行设定一个最大容量,第 26 行打印当前的最大容量。输出如下:
    图片25.png
    可以看到,默认容量高达约 4 T,这是在手机上几乎不可能达到的限制。而我们设定的值只有 100 K,这是很容易达到的。(此外,读者应该注意到此处的最大容量并不是我们给定的值 100000,而是 102400。这是因为数据库的容量大小必须是页大小的整数倍,如果不足就向上补齐到整数倍,所以最终数值将略大于给定的数值。除此之外,这个值还应该大于当前数据库的容量,也就是说,不能将数据库的最大容量设置为小于当前容量。不过这里我们的应用是第一次运行,所以不会影响。)
    也就是说,如果我们设定了最大容量,就有可能因为这个原因而发生这个错误。反之,若使用默认容量,则几乎不会因为这个原因发生这个错误。
    2. 手机剩余存储空间已满;
    承接上面的分析。如果数据库的最大容量是默认值,或者虽然设定了最大容量,但是最大容量依然大于实际数据量(需要注意的是,实际数据库大小会大于数据库所包含的记录的数据大小,我想这不难理解。),那么就可能是第二个原因导致的,那就是手机剩余存储空间已满。
    注意,一般情况下,使用 openOrCreateDatabase 创建的数据库文件默认放在手机内部存储器中,而不是 SD 卡中。所以这里所谓的“disk is full”是指手机内部存储空间已满,而不是 SD 卡已满。当然在某些情况下,比如应用安装在 SD 卡上时,数据库文件会跟着放在 SD 卡上,那么“disk is full”就是指 SD 卡已满。

    5 c, t: c9 z: y1 j【解决方案】, F9 l: o! l' A/ n
    3 T) j  j1 z* A% H# U8 `/ \0 E

    8 p- r9 t0 j7 T! L+ j% n: \  N. c4 \5 v
    1. 如果是由于限制了数据库最大体积导致的,如果条件允许,可以考虑放松限制。如果这个数据库是别人提供的,那么可以使用 getMaximumSize 获取当前最大容量。
    2. 如果是手机剩余存储空间不足导致的,则可以提醒用户清理垃圾,腾出内部空间。如果是并不敏感的数据,比如并不敏感的缓存数据,可以考虑放到 SD 卡中去。如果数据量非常大,比如视频缓存,更应该考虑放到 SD 卡中去。若是要避免此类异常的发生,可以事先统计剩余存储空间的大小,以作出合理安排。

    3 Z, f. r' K+ H9 |; [/ S* i) F9 e/ k* _( ?
    1 I! d" y! `- k$ l. Y" e, V

    9 K9 r% @+ h1 c# z3 \5 c3 R8 ^' h* `! x: N7 T# G! F
    . ?) O! l% D5 a4 m
    4 d  ^' Q" r4 I) m8 d5 N7 }" J

    2 B3 s+ e- J' ?9 u
    使用道具 举报 回复
    发表于 2016-5-20 09:22:54
    同样遇到了这个问题。
    使用道具 举报 回复 支持 反对
    您需要登录后才可以回帖 登录

    本版积分规则