MySQL存储图片读取图片

MySQL存储图片读取图片

注意!!!

图片是否能够显示完全有一个注意点 数据表中的BLOB类型设置是否够大

1、MySQL有四种BLOB类型: ·

tinyblob:仅255个字符

blob:最大限制到65K字节

mediumblob:限制到16M字节

longblob:可达4GB

2、除了类型对后面存取文件大小有限制,还要修改mysql的配置文件。

Windows、linux基本一样通过修改文件my.ini或my.cnf文件,在文件中增加 max_allowed_packet=10M(就是最大10M,mysql默认似乎1MB,增加前先查找一下确保没有设置过)

3、做了以上设置后,如果上传较大一点文件时或者某些文件时还是出错,如报一些乱码,估计就是下面的问题了。 数据库或表的字符集问题,如hibernate连接使用utf-8,表是gbk等,一般只要设置hibernate中数据连接部分就行,如 jdbc:mysql://192.168.0.4:3306/test?useUnicode=true&characterEncoding=UTF-8

读写流程图

如何从磁盘中读取图片数据

//从选取的文件中读取图片数据

int ReadImg(char *filename ,char *buffer) //filename:用来存储 Path+filename buffer:用来存储

{

if (NULL == filename || buffer == NULL)

{

return -1;

}

//打开文件

FILE* fp = fopen(filename, "rb");//rb 以读的方式打开

//判断是否成功打开了文件

if (NULL == fp )

{

printf("Fopen fail! \n");

return -2;

}

//测量文件字节数(偏移量 三板斧 都得要

fseek(fp, 0, SEEK_END);////将位置指针移动到文件末尾

int length = ftell(fp); // file size 确定文件的大小

fseek(fp, 0, SEEK_SET);//将位置指针移动到文件开头

int size = fread(buffer, 1,length,fp); //每次读取一个字节 从fp的指向开始 每次读1个字节 存放到buffer中 要执行length次

//判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小

if (size != length)

{

printf("FileRead error!%d \n",size);

return -3;

}

//关闭文件

fclose(fp);

}

如何把数据库中的图片数据存放到文件中

//将图片数据写入磁盘

int WirteImg(char* filename, char* buffer, int length) //写到哪个文件中 写入的数据是哪些 写入的长度是多少

{

if (filename == NULL || buffer == NULL || length <= 0) return -1;

FILE* fp = fopen(filename,"wb"); //wb 以写的方式打开

//判断是否成功打开了文件

if (NULL == fp)

{

printf("Fopen fail! \n");

return -2;

}

int size = fwrite(buffer, 1, length, fp);//每次读取一个字节 从fp的指向存放 每次读1个字节 要执行length次

//判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小

if (size != length)

{

printf("FileWrite error!%d \n", size);

return -3;

}

fclose(fp);

}

在表中增加一行为我们的图片存储做准备\

alter table TB_USER ADD UIMG BLOB;

MySQL写入数据

//数据库中存储图片数据

int MySQL_WriteImg(MYSQL *mysql,char *buffer, int length)

{

if (mysql == NULL || buffer == NULL || length <= 0) return -1;

MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存

int ret = mysql_stmt_prepare(stmt, SQL_INSERT_TB_USER_IMG, strlen(SQL_INSERT_TB_USER_IMG));

if (ret)

{

printf("mysql_stmt_prepare is error ! %s \n",mysql_error(mysql));

return -2;

}

//绑定数据

MYSQL_BIND parme = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用

parme.buffer_type = MYSQL_TYPE_LONG_BLOB;

parme.buffer = NULL;

parme.is_null = 0;

parme.length = NULL;

ret = mysql_stmt_bind_param(stmt,&parme);

if (ret)

{

printf("mysql_stmt_bind_param is error ! %s \n", mysql_error(mysql));

return -3;

}

//发送数据到数据库服务器中

ret = mysql_stmt_send_long_data(stmt, 0, buffer, length);

if (ret)

{

printf("mysql_stmt_send_long_data is error ! %s \n", mysql_error(mysql));

return -4;

}

//存储到表中

ret = mysql_stmt_execute(stmt);

if (ret)

{

printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));

return -5;

}

//以上执行完毕关闭stmt

ret = mysql_stmt_close(stmt);

if (ret)

{

printf("mysql_stmt_close is error ! %s \n", mysql_error(mysql));

return -6;

}

return ret;

}

MySQL读取数据

//从数据库中读取图片资源写入到磁盘

int MySQL_ReadImg(MYSQL *mysql,char * buffer, int length)

{

if (mysql == NULL || buffer == NULL || length <= 0) return -1;

MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存

//执行语句拿到返回值存储到stmt

int ret = mysql_stmt_prepare(stmt, SQL_SELECT_TB_USER_IMG, strlen(SQL_SELECT_TB_USER_IMG));

if (ret)

{

printf("mysql_stmt_prepare is error ! %s \n", mysql_error(mysql));

return -2;

}

//以下都是数据处理

//绑定结果

MYSQL_BIND result = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用

result.buffer_type = MYSQL_TYPE_LONG_BLOB;

//用于承载返回值的长度

unsigned long total_length = 0;

result.length = &total_length; //整张图片的数据长度

ret = mysql_stmt_bind_result(stmt, &result);

if (ret)

{

printf("mysql_stmt_bind_result is error ! %s \n", mysql_error(mysql));

return -3;

}

//执行语句

ret = mysql_stmt_execute(stmt);

if (ret)

{

printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));

return -4;

}

//返回结果

ret = mysql_stmt_store_result(stmt);

if (ret) {

printf("mysql_stmt_store_result : %s\n", mysql_error(mysql));

return -5;

}

//数据显示 取出单行可以不需要外循环

while (1)

{

//mysql_stmt_fetch 抓取返回的数据集:stmt 的下一行数据

ret = mysql_stmt_fetch(stmt);

if (ret != 0 && ret != MYSQL_DATA_TRUNCATED) break; // MYSQL_DATA_TRUNCATED 出现数据截短 块存储分片 \

当mysql_stmt_fetch返回0时意味着数据读取完毕

int start = 0;

while (start<(int)total_length)

{

result.buffer = buffer + start; //result.buffer和传入的参数buffer使用的是一个内存空间

result.buffer_length = 1; //buffer_length buffer的实际大小也就是每次接受数据的最大长度

mysql_stmt_fetch_column(stmt, &result, 0, start);//mysql_stmt_fetch_column:当前行获取一列数据 s

//stmt:存储结果;

//result:保存返回数据的缓存空间;

//0:因为我们查询的数据列只有一个所以是第0个写0

//start:从什么位置开始的偏移量

start += result.buffer_length; //获取下一个偏移量 也就是当前start代表的偏移量+buffer_length的长度

}

}

//关闭stmt

mysql_stmt_close(stmt);

//返回 数据总长

return total_length;

}

本文全部代码如下:

#include

#include

#include

//C U R D

//创建 更新 读取 删除

#define yang_db_server_ip "192.168.126.132" //数据库IP

#define yang_db_server_port 3306 //数据库链接的端口号

#define yang_db_server_definedb "yang_db" //该用户默认链接的数据库

#define yang_db_server_username "admin" //用户名

#define yang_db_server_password "123456" //密码

#define SQL_INSERT_TB_USER "insert TB_USER(UNAME,USEX) value('sunyu','woman');" //增加语句

#define SQL_INSERT_TB_USER_IMG "insert TB_USER(UNAME,USEX,UIMG) value('12345','woman',?);" //增加语句 在宏定义中?代表占位符因为不知道图片的内容所以使用?

#define SQL_SELECT_TB_USER "SELECT * FROM TB_USER;" //查询语句

#define SQL_SELECT_TB_USER_IMG "SELECT UIMG FROM TB_USER WHERE UNAME = '12345';" //查询语句

#define SQL_CALL_PROC_TB_USER "CALL PROC_DELETE_TBUSER('sun');" //调用删除的存储过程

#define FILE_IMAGE_LENGTH (1536*1824) //文件大小

int sel(MYSQL* sqldata)

{

//第一步

if (mysql_real_query(sqldata, SQL_SELECT_TB_USER, strlen(SQL_SELECT_TB_USER)))

{

printf("SQL_SELECT :%s \n ", mysql_error(sqldata));

}

//第二步

MYSQL_RES* res = mysql_store_result(sqldata);////保存返回语句的内容

if (res == NULL)

{

printf("mysql_store_result: %s \n", mysql_error(sqldata));

return -2;

}

//第三步 判断数据集合的行数

int rows = mysql_num_rows(res);

printf("Rows :%d \n", rows);

//列数

int cows = mysql_num_fields(res);

printf("Cows :%d \n", cows);

//第四步 将返回的数据逐行取出

MYSQL_ROW row; //row是一个存放数据的数组类似于C#中的sqlread函数

while ((row = mysql_fetch_row(res))) //判断行是否为空

{

int i = 0;

for (i = 0; i < cows; i++)

{

printf("%s \t", row[i]);

}

printf("\n");

}

mysql_free_result(res);

return 0;

//goto Exit;

}

//从选取的文件中读取图片数据

int ReadImg(char *filename ,char *buffer) //filename:用来存储 Path+filename buffer:用来存储

{

if (NULL == filename || buffer == NULL)

{

return -1;

}

//打开文件

FILE* fp = fopen(filename, "rb");//rb 以读的方式打开

//判断是否成功打开了文件

if (NULL == fp )

{

printf("Fopen fail! \n");

return -2;

}

//测量文件字节数(偏移量 三板斧 都得要

fseek(fp, 0, SEEK_END);////将位置指针移动到文件末尾

int length = ftell(fp); // file size 确定文件的大小

fseek(fp, 0, SEEK_SET);//将位置指针移动到文件开头

int size = fread(buffer, 1,length,fp); //每次读取一个字节 从fp的指向开始 每次读1个字节 存放到buffer中 要执行length次

//判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小

if (size != length)

{

printf("FileRead error ! %d \n",size);

return -3;

}

//关闭文件

fclose(fp);

//返回长度

return size;

}

//数据库中存储图片数据

int MySQL_WriteImg(MYSQL *mysql,char *buffer, int length)

{

if (mysql == NULL || buffer == NULL || length <= 0) return -1;

MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存

int ret = mysql_stmt_prepare(stmt, SQL_INSERT_TB_USER_IMG, strlen(SQL_INSERT_TB_USER_IMG));

if (ret)

{

printf("mysql_stmt_prepare is error ! %s \n",mysql_error(mysql));

return -2;

}

//绑定数据

MYSQL_BIND parme = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用

parme.buffer_type = MYSQL_TYPE_LONG_BLOB;

parme.buffer = NULL;

parme.is_null = 0;

parme.length = NULL;

ret = mysql_stmt_bind_param(stmt,&parme);

if (ret)

{

printf("mysql_stmt_bind_param is error ! %s \n", mysql_error(mysql));

return -3;

}

//发送数据到数据库服务器中

ret = mysql_stmt_send_long_data(stmt, 0, buffer, length);

if (ret)

{

printf("mysql_stmt_send_long_data is error ! %s \n", mysql_error(mysql));

return -4;

}

//存储到表中

ret = mysql_stmt_execute(stmt);

if (ret)

{

printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));

return -5;

}

//以上执行完毕关闭stmt

ret = mysql_stmt_close(stmt);

if (ret)

{

printf("mysql_stmt_close is error ! %s \n", mysql_error(mysql));

return -6;

}

return ret;

}

//从数据库中读取图片资源写入到磁盘

int MySQL_ReadImg(MYSQL *mysql,char * buffer, int length)

{

if (mysql == NULL || buffer == NULL || length <= 0) return -1;

MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存

//执行语句拿到返回值存储到stmt

int ret = mysql_stmt_prepare(stmt, SQL_SELECT_TB_USER_IMG, strlen(SQL_SELECT_TB_USER_IMG));

if (ret)

{

printf("mysql_stmt_prepare is error ! %s \n", mysql_error(mysql));

return -2;

}

//以下都是数据处理

//绑定结果

MYSQL_BIND result = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用

result.buffer_type = MYSQL_TYPE_LONG_BLOB;

//用于承载返回值的长度

unsigned long total_length = 0;

result.length = &total_length; //整张图片的数据长度

ret = mysql_stmt_bind_result(stmt, &result);

if (ret)

{

printf("mysql_stmt_bind_result is error ! %s \n", mysql_error(mysql));

return -3;

}

//执行语句

ret = mysql_stmt_execute(stmt);

if (ret)

{

printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));

return -4;

}

//返回结果

ret = mysql_stmt_store_result(stmt);

if (ret) {

printf("mysql_stmt_store_result : %s\n", mysql_error(mysql));

return -5;

}

//数据显示 取出单行可以不需要外循环

while (1)

{

//mysql_stmt_fetch 抓取返回的数据集:stmt 的下一行数据

ret = mysql_stmt_fetch(stmt);

if (ret != 0 && ret != MYSQL_DATA_TRUNCATED) break; // MYSQL_DATA_TRUNCATED 出现数据截短 块存储分片 \

当mysql_stmt_fetch返回0时意味着数据读取完毕

int start = 0;

while (start<(int)total_length)

{

result.buffer = buffer + start; //result.buffer和传入的参数buffer使用的是一个内存空间

result.buffer_length = 1; //buffer_length buffer的实际大小也就是每次接受数据的最大长度

mysql_stmt_fetch_column(stmt, &result, 0, start);//mysql_stmt_fetch_column:当前行获取一列数据 s

//stmt:存储结果;

//result:保存返回数据的缓存空间;

//0:因为我们查询的数据列只有一个所以是第0个写0

//start:从什么位置开始的偏移量

start += result.buffer_length; //获取下一个偏移量 也就是当前start代表的偏移量+buffer_length的长度

}

}

//关闭stmt

mysql_stmt_close(stmt);

//返回 数据总长

return total_length;

}

//将图片数据写入磁盘

int WirteImg(char* filename, char* buffer, int length) //写到哪个文件中 写入的数据是哪些 写入的长度是多少

{

if (filename == NULL || buffer == NULL || length <= 0) return -1;

FILE* fp = fopen(filename,"wb"); //wb 以写的方式打开

//判断是否成功打开了文件

if (NULL == fp)

{

printf("Fopen fail! \n");

return -2;

}

int size = fwrite(buffer, 1, length, fp);//每次读取一个字节 从fp的指向存放 每次读1个字节 要执行length次

//判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小

if (size != length)

{

printf("FileWrite error!%d \n", size);

return -3;

}

fclose(fp);

}

int main()

{

//注:mysql的两个接口以返回0作为失败

MYSQL mysql;

if (NULL == mysql_init(&mysql)) //初始化数据库

{

printf("mysql_init :%s \n", mysql_error(&mysql)); //mysql提供了统一的错误值

return -1;

}

//mysql_real_connect返回非0成功

if (!mysql_real_connect(&mysql, yang_db_server_ip,

yang_db_server_username, yang_db_server_password,

yang_db_server_definedb, yang_db_server_port, NULL, 0))//第一个参数是定义的数据库对象 第二个是IP地址 三四是用户名和密码 第五个是默认链接数据库名 第六个是端口号 七八置空

{

printf("mysql_real_connect:%s \n", mysql_error(&mysql));

goto Exit;

}

#if 1

sel(&mysql);

#endif

//读取磁盘的图片资源写入到mysql服务器中

#if 1

printf("case : mysql --> read image and write mysql\n");

char buffer[FILE_IMAGE_LENGTH] = { 0 };

int length = ReadImg("1.jpg", buffer); //图片和代码不在一个文件下用绝对路径,在可以直接写文件名

if (length < 0)

{

printf("length : %d \n", length);

goto Exit;

}

printf("length : %d \n", length);

MySQL_WriteImg(&mysql, buffer, length);

#endif // 1

//读取数据库中的图片资源并写入磁盘

#if 1

printf("case : mysql --> read mysql and write image\n");

char buffers[FILE_IMAGE_LENGTH] = { 0 };

memset(buffers, 0, FILE_IMAGE_LENGTH);

int len = MySQL_ReadImg(&mysql, buffers, FILE_IMAGE_LENGTH);

WirteImg("a.jpg", buffers,len);

#endif

#if 0

//insert----SQL

//mysql_real_query返回0成功

if (mysql_real_query(&mysql, SQL_INSERT_TB_USER, strlen(SQL_INSERT_TB_USER)))

{

printf("mysql_real_query :%s \n ", mysql_error(&mysql));

goto Exit;

}

#endif

#if 0

printf("case : mysql --> delete \n");

//delete----SQL

//mysql_real_query返回0成功

if (mysql_real_query(&mysql, SQL_CALL_PROC_TB_USER, strlen(SQL_CALL_PROC_TB_USER)))

{

printf("mysql_real_query :%s \n ", mysql_error(&mysql));

goto Exit;

}

#endif

#if 1

sel(&mysql);

#endif

Exit:

mysql_close(&mysql);

return 0;

}

相关推荐

如何转发视频到朋友圈 体育平台送365彩金

如何转发视频到朋友圈

07-05 👁️ 9187
网络棋牌游戏排行榜 365体育旧版本怎么下载

网络棋牌游戏排行榜

07-03 👁️ 8558
世界杯 2022 臂章種類 365体育投注网址亚洲下载

世界杯 2022 臂章種類

06-28 👁️ 2129