如何在SQLite中存储和读取BLOB?用ContentValues存入JPG图片的方法
刚好我之前处理过类似的需求,把网络JPG存入SQLite其实没那么复杂,分两步走就搞定了:先把网络图片转成byte数组,再用ContentValues存进数据库。我给你详细拆解一下:
第一步:从网络获取JPG并转换为byte[]
首先你需要从网络拉取图片的输入流,再把输入流转换成byte数组。这里用原生的HttpURLConnection举个例子,注意网络操作绝对不能放在主线程,要放在子线程、AsyncTask或者协程里执行:
public byte[] getImageBytesFromUrl(String imageUrl) throws IOException { URL url = new URL(imageUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { // 设置请求超时时间 connection.setConnectTimeout(5000); connection.setReadTimeout(5000); InputStream inputStream = connection.getInputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int bytesRead; // 逐块读取输入流并写入输出流 while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } return outputStream.toByteArray(); } finally { // 一定要断开连接释放资源 connection.disconnect(); } }
如果你用Kotlin或者OkHttp,代码会更简洁,比如用OkHttp的话:
val client = OkHttpClient() val request = Request.Builder().url(imageUrl).build() client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("请求失败: ${response.code}") // 直接获取byte数组 return response.body?.bytes() ?: throw IOException("图片内容为空") }
第二步:用ContentValues将byte[]存入SQLite
首先你的数据库表需要有一个BLOB类型的字段来存储byte数组,建表SQL大概是这样:
CREATE TABLE IF NOT EXISTS network_images ( id INTEGER PRIMARY KEY AUTOINCREMENT, image_blob BLOB NOT NULL, source_url TEXT NOT NULL -- 可以存原URL,方便后续溯源 );
然后用ContentValues把byte数组塞进去,再调用SQLite的插入方法:
try { // 先获取图片的byte数组(注意这里要在子线程执行) byte[] imageBytes = getImageBytesFromUrl("https://example.com/your-image.jpg"); ContentValues values = new ContentValues(); values.put("image_blob", imageBytes); values.put("source_url", "https://example.com/your-image.jpg"); // 获取可写的数据库实例 SQLiteDatabase db = yourDbHelper.getWritableDatabase(); // 插入数据,返回的rowId是新插入行的ID,-1代表插入失败 long rowId = db.insert("network_images", null, values); if (rowId != -1) { Log.d("DB", "图片存入成功,行ID:" + rowId); } else { Log.e("DB", "图片存入失败"); } // 关闭数据库释放资源 db.close(); } catch (IOException e) { e.printStackTrace(); // 处理网络请求异常 } catch (SQLException e) { e.printStackTrace(); // 处理数据库操作异常 }
额外提醒
- 如果图片体积很大(比如超过1MB),不建议存在数据库里,更优的方案是把图片下载到本地存储,数据库只存图片的本地路径,这样能避免数据库体积膨胀、读写性能下降的问题。
- 记得处理各种异常:网络请求失败、输入流读取失败、数据库操作失败等,避免APP崩溃。
- 读取的时候,只需要从数据库取出byte数组,再转成
Bitmap即可:Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
内容的提问来源于stack exchange,提问作者Augusto
相关产品推荐
相关产品推荐

