赞
踩
图片是否能够显示完全有一个注意点 数据表中的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;
- //数据库中存储图片数据
- 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;
- }

本文全部代码如下:
- #include <stdio.h>
- #include <mysql.h>
- #include <string.h>
-
-
- //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;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。