我写了一个小的Java程序,读取图像文件(jpg / jpeg)并将它们插入到数据库表
covers.cover 中,该表的类型为 bytea 。
我相当确定传递给Java addCover(int riddim_id,byte [] cover,byte [] thumbnail)方法的 byte [] cover 参数包含有效的jpeg数据(我已经通过将其写入.jpeg文件进行了测试,显示正常)。
调用数据库函数 add_cover(riddim INT,cover BYTEA,thumbnail BYTEA)似乎是正确的;调用后表中有数据,我没有收到任何SQL错误。
然而,数据看起来有些像
\377\330\377\340\000\020JFIF\000\001\001\001\001,\001,\000\000\377\333\000C\000\013\010\010\010\011\010\014\011\011\014\021\013\012\013\021\024\017\014\014\017\024\027\022\022\022\022\022\027\030\023\024\024\024\024\023\030\026\032\033\034\033\032\026""$$"".....0000000000\377\333\000C\001\014\014\014\020\020\020\027\021\021\027\030\024\023\024\030\036\033\034\034\033\036$\036\036\037\036\036$)# #)&($$$(&++))++000000000000000\377\300\000\021\010\005\200\005\230\003\001\021\000\002\021\001\003\021\001\377\304\000\033\000\000\003\000\003\001\001\000\000\000\000\000\000\000\000\000\000\000\001\002\003\004\006\005\007\377\304\000U\020\000\001\002\004\003\005\004\010\003\006\005\003\003\001\001\021\001\002\021\000!1A\003\022Q\004"2Ba\005\023bq\006CRr\201\221\241\3603\261\301\024#c\202\321
等等,这些数据对我来说似乎不是有效的数据。我预计会有更加统一的内容(少量特殊字符像,
, "
和$
),像\x01E25A43
这样。
当我打开http://foo.bar/image.php
时,出现了错误数据的提示,Firefox无法显示图片。下面是PHP脚本:
我猜测我没有正确地使用BYTEA字段,但我想不出错在哪里。你有什么建议吗?
数据库表格如下:
CREATE TABLE covers (
cover_id SERIAL PRIMARY KEY,
riddim_id SERIAL UNIQUE REFERENCES riddims (riddim_id),
coverhash VARCHAR(32) NOT NULL UNIQUE,
cover BYTEA NOT NULL,
thumbnail BYTEA NOT NULL
);
我使用Java调用的数据库函数如下:
CREATE OR REPLACE FUNCTION add_cover(_riddim_id INT, _cover BYTEA, _thumbnail BYTEA) RETURNS INTEGER AS $$
DECLARE
_cover_id INT;
BEGIN
SELECT cover_id INTO _cover_id FROM covers WHERE riddim_id = _riddim_id;
IF (_cover_id IS NULL) THEN
INSERT INTO covers (riddim_id, coverhash, cover, thumbnail) VALUES (
_riddim_id,
md5(_cover),
_cover,
_thumbnail
) RETURNING cover_id INTO _cover_id;
END IF;
RETURN _cover_id;
END;
$$ LANGUAGE plpgsql;
使用JDBC连接器调用上述数据库函数的Java方法如下:
private int addCover(int riddim_id, byte[] cover, byte[] thumbnail)
throws SQLException {
int cover_id;
try (CallableStatement cs = conn.prepareCall("{ ? = call add_cover(?, ?, ?) }")) {
cs.registerOutParameter(1, Types.INTEGER);
cs.setInt(2, riddim_id);
cs.setBytes(3, cover);
cs.setBytes(4, thumbnail);
cs.execute();
cover_id = cs.getInt(1);
}
return (cover_id != 0) ? cover_id : -1;
}
我在谷歌上找到的PHP脚本将数据以image/jpeg的形式发送给浏览器:
<?php
// Connect to the database
$dbconn = pg_connect("<censored>");
// Get the bytea data
$res = pg_query("SELECT cover FROM covers WHERE cover_id = 11");
$raw = pg_fetch_result($res, 'cover');
// Convert to binary and send to the browser
header('Content-type: image/jpeg');
echo pg_unescape_bytea($raw);
?>
我正在运行 PostgreSQL 版本 9.4.4,使用 postgresql-9.4-1202.jdbc41.jar。
escape
表示(八进制转义)。尝试使用SET bytea_output ='hex'
查看十六进制表示。验证数据库中的内容与提供给Java应用程序的内容相同。 - Craig Ringer