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

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

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

    [LV.2]偶尔看看I

    107

    主题

    1159

    帖子

    4092

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    4092
    发表于 2016-5-17 17:53:20
    出错堆栈
    9 _" L& ~4 M2 w1 J. W5 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)   
    
    % B" `! O  u0 Q# B
    " T# f* Q5 }6 v0 T7 D: e. D
    【出错代码】
    % |4 E) K+ \3 N" Q% a
    类:me.bfbrmt.bugly2.MainActivity
    22.png 4 i! w) V/ }( l# Y
    ' M4 L$ ]7 t% ~
    代码片段(第40行):
    2 p" l& [9 i) e( Y; G* @: G
    " w) H1 l8 E4 Y; s$ H. _7 q【出错原因】
    ( {) e$ t# u6 @' w. d) u* A0 b% i
    从异常的完整描述:
    “android.database.sqlite.SQLiteFullException: database or disk is full (code 13)”
    很容易看出,这是因为数据库的体积达到最大限制或者磁盘已满。也就是说数据量太大,或者磁盘空间不足。
    2 n' H3 {; z+ v
    分析:
    注意第 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 卡已满。

    + s- B/ Z' r: i9 J【解决方案】, }! S, M( ^% {+ q/ d

    ) P4 f' T: T4 p, v: g4 L- ~/ M& j  O( m- g
    1. 如果是由于限制了数据库最大体积导致的,如果条件允许,可以考虑放松限制。如果这个数据库是别人提供的,那么可以使用 getMaximumSize 获取当前最大容量。
    2. 如果是手机剩余存储空间不足导致的,则可以提醒用户清理垃圾,腾出内部空间。如果是并不敏感的数据,比如并不敏感的缓存数据,可以考虑放到 SD 卡中去。如果数据量非常大,比如视频缓存,更应该考虑放到 SD 卡中去。若是要避免此类异常的发生,可以事先统计剩余存储空间的大小,以作出合理安排。
    1 j# p8 c3 t* T/ u8 r8 L

    ! X- F" U3 n/ A% z* A
    + ^! E) r! {0 ]3 g7 G7 t8 v  l' v  a) r9 U4 `5 U! w
    . s8 e- c, w8 T+ Z5 I" G0 D! X9 i

    1 H2 Y+ S6 q7 ?6 F2 E* n
    ' U1 c% B3 r2 _9 o' F" ]1 x) Y. t* Q3 w0 M! D8 L! V
    使用道具 举报 回复
    发表于 2016-5-20 09:22:54
    同样遇到了这个问题。
    使用道具 举报 回复 支持 反对
    您需要登录后才可以回帖 登录

    本版积分规则