使用readBin读取PNG图片后结构损坏,写入数据库字节异常求助
问题根源与解决方法
你的问题出在把二进制raw向量转成字符串拼接SQL的操作上,这直接破坏了图片的二进制结构,同时手动拼接SQL也会导致数据转义错误,最终写入数据库的是损坏的文本而非有效Blob。
错误点拆解
- raw向量转字符串的致命问题:
paste(readBin(...), collapse="")会把每个二进制字节(比如0x89)转成字符串"89",拼接后原15698字节的二进制数据会变成3万多字符的文本,完全丢失了二进制结构,写入数据库后自然无法还原成有效图片。 - 手动拼接SQL的风险:
二进制数据中包含大量特殊字符(比如引号、控制字符),直接拼进SQL语句会破坏语法,同时数据库会把这些内容当成文本存储,而非Blob类型。
修正后的代码步骤
1. 正确读取图片二进制数据
直接读取为raw向量,不要做字符串转换,用文件大小指定读取量更精准:
fileName <- "S:\\Filename.png" # 读取完整的二进制数据 plotBinary <- readBin(fileName, what = "raw", n = file.info(fileName)$size)
2. 在RStudio中查看图片
可以用png包读取并显示:
library(png) library(grid) # 读取图片并显示 img <- readPNG(fileName) grid.raster(img)
3. 用参数化查询写入Blob数据库
绝对不要手动拼接SQL,用RMariaDB的参数化查询直接传入raw向量,数据库会自动处理Blob类型:
library(RMariaDB) # 建立连接 con <- dbConnect(MariaDB(), dbname = "db1") # 参数化SQL,用?作为占位符 query <- "REPLACE INTO Images (Time, Image) VALUES (?, ?)" # 传入参数:时间和二进制Blob数据 result <- dbSendStatement(con, query, params = list(Sys.time(), plotBinary)) dbClearResult(result) # 记得断开连接 dbDisconnect(con)
还原验证(可选)
如果要从数据库读回验证,可以用以下代码:
con <- dbConnect(MariaDB(), dbname = "db1") # 查询最新的图片数据 query <- "SELECT Image FROM Images ORDER BY Time DESC LIMIT 1" img_blob <- dbFetch(dbSendQuery(con, query))$Image[[1]] dbDisconnect(con) # 写入文件验证 writeBin(img_blob, "test_output.png")
内容的提问来源于stack exchange,提问作者Sundancer
相关产品推荐
相关产品推荐

