java sqlite储存图片_sqlite3的图片的(二进制数据)存取操作

sqlite3的图片的(二进制数据)存取操作

前言

上篇介绍了sqlite3的一些常用插入操作方法和注意事项,在实际项目中遇到了图片缓存的问题,由于服务器不是很稳定,且受到外界环境的干扰(例如断电,图片存储挂掉,图片存储速度过慢,造成的接口调用失败等等),一个数据结构中除了普通字段(int string),还包括图片数据,所以还需要将图片数据进行缓存,图片缓存与普通的数据库字段值缓存有所不同,下面介绍一下简单方法。

开发示例

此demo仅供学习使用。

sqlite3支持对二进制数据的缓存,在实际的编程开发当中我们经常要处理一些大容量二进制数据的存储,如图片、音乐、视频等等。对于这些二进制数据,我们不能像处理普通的文本那样,但是我们可以用blob来存储。sqlite官方文档https://www.sqlite.org/datatype3.html#section_1对blob 字段的解释是

BLOB. The value is a blob of data, stored exactly as it was input。

即数据不做任何转换,以输入形式存储。因此 BOLB通常用来存储二进制大对象。

sqlite3_bind_blob示例代码

char* cmdCreatBlobTable = "create table SqliteBlobTest (id integer , pic blob); //首先创建一个可插入blob类型的表 。

sqlite3* db = NULL;

char * errorMessage = NULL;

int iResult = sqlite3_open("SqliteTest.db", &db);

sqlite3_exec(db,"drop table if exists SqliteBlobTest",0,0,0);

iResult = sqlite3_exec(db, cmdCreatBlobTable, NULL, NULL, &errorMessage);

if (SQLITE_OK != iResult)

{

cout<

break;

}

sqlite3_stmt *stmt; //声明

const char* sql = "insert into SqliteBlobTest values(1,?)";

char* pPicData = "this is a pic data" ;

sqlite3_prepare(db,sql,strlen(sql),&stmt,0); //完成对sql语句的解析

{

sqlite3_bind_blob(stmt,1,pPicData, strlen(pPicData), NULL);//1代表第一个?

sqlite3_step(stmt); //将数据写入数据库中

}

sqlite3_prepare(db, "select * from SqliteBlobTest", -1, &stmt, 0);

int result = sqlite3_step(stmt);

int id = 0,len = 0;

char picData[128] = {0};

if (result == SQLITE_ROW) //查询成功返回的是SQLITE_ROW

{

cout<

id = sqlite3_column_int(stmt, 0); //从0开始计算,id为0,picdata 为1;

const void * pReadPicData = sqlite3_column_blob(stmt, 1); //读取数据,返回一个指针

len = sqlite3_column_bytes(stmt, 1); //返回数据大小

memcpy(picData, pReadPicData, len); //把数据拷贝出来

}

else

{

cout<

}

sqlite3_finalize(stmt); //把刚才分配的内容析构掉

cout<

测试结果

0adbc53d100239493e66be28e6353545.png

d5b8863d8ac7c80a9e392eea17b6e39e.png

总结

经过这一个月工作之余的优化,终于把项目的缓存给做好了,其中也遇到了很多问题,例如sqlite的编码转换,图片缓存速度慢,还有db-journal文件操作慢,以及如何直观的让sqliteDb大小自动展现,自己也是查了官方英文文档才一步步解决各种坑。总结的好处就在于能够温故知新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLite3数据库并不适合直接存储图片,因为图片文件通常较大,存储在数据库中会占用大量的空间。一般来说,我们可以将图片存储在本地,然后在数据库中只存储图片的路径或文件名,这样可以节省数据库存储空间,同时也方便对图片进行管理。 如果你想要存储drawable类型的图片,可以先将其转换成Bitmap对象,然后将Bitmap对象转换成字节数组,最后将字节数组存储到数据库中。在读取图片时,则需要将字节数组转换回Bitmap对象,再显示在界面上。 以下是一个简单的示例代码,假设你的drawable图片名称为my_image: ``` // 将drawable图片转换成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); // 将Bitmap对象转换成字节数组 ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); // 将字节数组存储到数据库中 String sql = "INSERT INTO images (name, data) VALUES (?, ?)"; SQLiteStatement statement = db.compileStatement(sql); statement.bindString(1, "my_image"); statement.bindBlob(2, byteArray); statement.execute(); ``` 读取图片时,可以使用如下代码: ``` // 查询数据库获取字节数组 String sql = "SELECT data FROM images WHERE name = 'my_image'"; Cursor cursor = db.rawQuery(sql, null); byte[] byteArray = cursor.getBlob(0); // 将字节数组转换成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); // 显示图片 ImageView imageView = findViewById(R.id.imageView); imageView.setImageBitmap(bitmap); ``` 注意,以上代码仅为示例代码,实际应用中可能需要进行异常处理、关闭流等操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值