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

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

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

    [LV.2]偶尔看看I

    107

    主题

    1039

    帖子

    3679

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    3679
    发表于 2016-5-17 17:53:20
    出错堆栈
    * ^/ H. B6 X3 v; q
    [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)   
    

    ' j* A1 [( b. |/ j3 Y0 p6 J
    " l3 {- B" n7 s) f; O【出错代码】
    * L1 t# ?1 i1 [  `) |6 H
    类:me.bfbrmt.bugly2.MainActivity
    22.png
    7 B2 W$ c) [) Q4 [( I# n; ~( V
    6 L  U* Y/ D1 v) w代码片段(第40行):
    / B9 a% r7 V' l2 \- g6 |7 p$ P( }) }2 a3 Q) G: \. K
    【出错原因】8 j( f0 h* b" k+ Y
    从异常的完整描述:
    “android.database.sqlite.SQLiteFullException: database or disk is full (code 13)”
    很容易看出,这是因为数据库的体积达到最大限制或者磁盘已满。也就是说数据量太大,或者磁盘空间不足。
    ; [/ m0 m+ @  E' f4 F# s1 J
    分析:
    注意第 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 卡已满。
    ( G/ X# o4 N! L% K
    【解决方案】
    , T' a0 B2 }  d7 j! X; w1 q. @6 ^2 F" V& u% a+ w/ C
    8 Q2 g5 {6 `" A1 [) C
    1. 如果是由于限制了数据库最大体积导致的,如果条件允许,可以考虑放松限制。如果这个数据库是别人提供的,那么可以使用 getMaximumSize 获取当前最大容量。
    2. 如果是手机剩余存储空间不足导致的,则可以提醒用户清理垃圾,腾出内部空间。如果是并不敏感的数据,比如并不敏感的缓存数据,可以考虑放到 SD 卡中去。如果数据量非常大,比如视频缓存,更应该考虑放到 SD 卡中去。若是要避免此类异常的发生,可以事先统计剩余存储空间的大小,以作出合理安排。
    3 n9 I* J) I( B( \

    , @7 u9 d- S& d! z' R# C; g! [5 U* `- |3 F

    + u) {1 H, ^  M+ t" p& ]1 ^/ l( }/ j8 r4 V, R- m

    / ^/ C2 T$ \5 i4 N, ?, a7 u' u0 |' Q% }5 G6 W  J1 S# i) j$ ~( _

    / u1 s) ?. h+ H, N" [4 d
    使用道具 举报 回复
    发表于 2016-5-20 09:22:54
    同样遇到了这个问题。
    使用道具 举报 回复 支持 反对
    您需要登录后才可以回帖 登录

    本版积分规则