当前位置:   article > 正文

MySQL存储图片读取图片_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

读写流程图
读写流程图
 如何从磁盘中读取图片数据
  1. //从选取的文件中读取图片数据
  2. int ReadImg(char *filename ,char *buffer) //filename:用来存储 Path+filename buffer:用来存储
  3. {
  4. if (NULL == filename || buffer == NULL)
  5. {
  6. return -1;
  7. }
  8. //打开文件
  9. FILE* fp = fopen(filename, "rb");//rb 以读的方式打开
  10. //判断是否成功打开了文件
  11. if (NULL == fp )
  12. {
  13. printf("Fopen fail! \n");
  14. return -2;
  15. }
  16. //测量文件字节数(偏移量 三板斧 都得要
  17. fseek(fp, 0, SEEK_END);将位置指针移动到文件末尾
  18. int length = ftell(fp); // file size 确定文件的大小
  19. fseek(fp, 0, SEEK_SET);//将位置指针移动到文件开头
  20. int size = fread(buffer, 1,length,fp); //每次读取一个字节 从fp的指向开始 每次读1个字节 存放到buffer中 要执行length次
  21. //判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小
  22. if (size != length)
  23. {
  24. printf("FileRead error!%d \n",size);
  25. return -3;
  26. }
  27. //关闭文件
  28. fclose(fp);
  29. }
如何把数据库中的图片数据存放到文件中
  1. //将图片数据写入磁盘
  2. int WirteImg(char* filename, char* buffer, int length) //写到哪个文件中 写入的数据是哪些 写入的长度是多少
  3. {
  4. if (filename == NULL || buffer == NULL || length <= 0) return -1;
  5. FILE* fp = fopen(filename,"wb"); //wb 以写的方式打开
  6. //判断是否成功打开了文件
  7. if (NULL == fp)
  8. {
  9. printf("Fopen fail! \n");
  10. return -2;
  11. }
  12. int size = fwrite(buffer, 1, length, fp);//每次读取一个字节 从fp的指向存放 每次读1个字节 要执行length次
  13. //判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小
  14. if (size != length)
  15. {
  16. printf("FileWrite error!%d \n", size);
  17. return -3;
  18. }
  19. fclose(fp);
  20. }

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

alter table TB_USER ADD UIMG BLOB;
MySQL写入数据
  1. //数据库中存储图片数据
  2. int MySQL_WriteImg(MYSQL *mysql,char *buffer, int length)
  3. {
  4. if (mysql == NULL || buffer == NULL || length <= 0) return -1;
  5. MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存
  6. int ret = mysql_stmt_prepare(stmt, SQL_INSERT_TB_USER_IMG, strlen(SQL_INSERT_TB_USER_IMG));
  7. if (ret)
  8. {
  9. printf("mysql_stmt_prepare is error ! %s \n",mysql_error(mysql));
  10. return -2;
  11. }
  12. //绑定数据
  13. MYSQL_BIND parme = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用
  14. parme.buffer_type = MYSQL_TYPE_LONG_BLOB;
  15. parme.buffer = NULL;
  16. parme.is_null = 0;
  17. parme.length = NULL;
  18. ret = mysql_stmt_bind_param(stmt,&parme);
  19. if (ret)
  20. {
  21. printf("mysql_stmt_bind_param is error ! %s \n", mysql_error(mysql));
  22. return -3;
  23. }
  24. //发送数据到数据库服务器中
  25. ret = mysql_stmt_send_long_data(stmt, 0, buffer, length);
  26. if (ret)
  27. {
  28. printf("mysql_stmt_send_long_data is error ! %s \n", mysql_error(mysql));
  29. return -4;
  30. }
  31. //存储到表中
  32. ret = mysql_stmt_execute(stmt);
  33. if (ret)
  34. {
  35. printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));
  36. return -5;
  37. }
  38. //以上执行完毕关闭stmt
  39. ret = mysql_stmt_close(stmt);
  40. if (ret)
  41. {
  42. printf("mysql_stmt_close is error ! %s \n", mysql_error(mysql));
  43. return -6;
  44. }
  45. return ret;
  46. }
MySQL读取数据
  1. //从数据库中读取图片资源写入到磁盘
  2. int MySQL_ReadImg(MYSQL *mysql,char * buffer, int length)
  3. {
  4. if (mysql == NULL || buffer == NULL || length <= 0) return -1;
  5. MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存
  6. //执行语句拿到返回值存储到stmt
  7. int ret = mysql_stmt_prepare(stmt, SQL_SELECT_TB_USER_IMG, strlen(SQL_SELECT_TB_USER_IMG));
  8. if (ret)
  9. {
  10. printf("mysql_stmt_prepare is error ! %s \n", mysql_error(mysql));
  11. return -2;
  12. }
  13. //以下都是数据处理
  14. //绑定结果
  15. MYSQL_BIND result = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用
  16. result.buffer_type = MYSQL_TYPE_LONG_BLOB;
  17. //用于承载返回值的长度
  18. unsigned long total_length = 0;
  19. result.length = &total_length; //整张图片的数据长度
  20. ret = mysql_stmt_bind_result(stmt, &result);
  21. if (ret)
  22. {
  23. printf("mysql_stmt_bind_result is error ! %s \n", mysql_error(mysql));
  24. return -3;
  25. }
  26. //执行语句
  27. ret = mysql_stmt_execute(stmt);
  28. if (ret)
  29. {
  30. printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));
  31. return -4;
  32. }
  33. //返回结果
  34. ret = mysql_stmt_store_result(stmt);
  35. if (ret) {
  36. printf("mysql_stmt_store_result : %s\n", mysql_error(mysql));
  37. return -5;
  38. }
  39. //数据显示 取出单行可以不需要外循环
  40. while (1)
  41. {
  42. //mysql_stmt_fetch 抓取返回的数据集:stmt 的下一行数据
  43. ret = mysql_stmt_fetch(stmt);
  44. if (ret != 0 && ret != MYSQL_DATA_TRUNCATED) break; // MYSQL_DATA_TRUNCATED 出现数据截短 块存储分片 \
  45. 当mysql_stmt_fetch返回0时意味着数据读取完毕
  46. int start = 0;
  47. while (start<(int)total_length)
  48. {
  49. result.buffer = buffer + start; //result.buffer和传入的参数buffer使用的是一个内存空间
  50. result.buffer_length = 1; //buffer_length buffer的实际大小也就是每次接受数据的最大长度
  51. mysql_stmt_fetch_column(stmt, &result, 0, start);//mysql_stmt_fetch_column:当前行获取一列数据 s
  52. //stmt:存储结果;
  53. //result:保存返回数据的缓存空间;
  54. //0:因为我们查询的数据列只有一个所以是第0个写0
  55. //start:从什么位置开始的偏移量
  56. start += result.buffer_length; //获取下一个偏移量 也就是当前start代表的偏移量+buffer_length的长度
  57. }
  58. }
  59. //关闭stmt
  60. mysql_stmt_close(stmt);
  61. //返回 数据总长
  62. return total_length;
  63. }

本文全部代码如下:

  1. #include <stdio.h>
  2. #include <mysql.h>
  3. #include <string.h>
  4. //C U R D
  5. //创建 更新 读取 删除
  6. #define yang_db_server_ip "192.168.126.132" //数据库IP
  7. #define yang_db_server_port 3306 //数据库链接的端口号
  8. #define yang_db_server_definedb "yang_db" //该用户默认链接的数据库
  9. #define yang_db_server_username "admin" //用户名
  10. #define yang_db_server_password "123456" //密码
  11. #define SQL_INSERT_TB_USER "insert TB_USER(UNAME,USEX) value('sunyu','woman');" //增加语句
  12. #define SQL_INSERT_TB_USER_IMG "insert TB_USER(UNAME,USEX,UIMG) value('12345','woman',?);" //增加语句 在宏定义中?代表占位符因为不知道图片的内容所以使用?
  13. #define SQL_SELECT_TB_USER "SELECT * FROM TB_USER;" //查询语句
  14. #define SQL_SELECT_TB_USER_IMG "SELECT UIMG FROM TB_USER WHERE UNAME = '12345';" //查询语句
  15. #define SQL_CALL_PROC_TB_USER "CALL PROC_DELETE_TBUSER('sun');" //调用删除的存储过程
  16. #define FILE_IMAGE_LENGTH (1536*1824) //文件大小
  17. int sel(MYSQL* sqldata)
  18. {
  19. //第一步
  20. if (mysql_real_query(sqldata, SQL_SELECT_TB_USER, strlen(SQL_SELECT_TB_USER)))
  21. {
  22. printf("SQL_SELECT :%s \n ", mysql_error(sqldata));
  23. }
  24. //第二步
  25. MYSQL_RES* res = mysql_store_result(sqldata);保存返回语句的内容
  26. if (res == NULL)
  27. {
  28. printf("mysql_store_result: %s \n", mysql_error(sqldata));
  29. return -2;
  30. }
  31. //第三步 判断数据集合的行数
  32. int rows = mysql_num_rows(res);
  33. printf("Rows :%d \n", rows);
  34. //列数
  35. int cows = mysql_num_fields(res);
  36. printf("Cows :%d \n", cows);
  37. //第四步 将返回的数据逐行取出
  38. MYSQL_ROW row; //row是一个存放数据的数组类似于C#中的sqlread函数
  39. while ((row = mysql_fetch_row(res))) //判断行是否为空
  40. {
  41. int i = 0;
  42. for (i = 0; i < cows; i++)
  43. {
  44. printf("%s \t", row[i]);
  45. }
  46. printf("\n");
  47. }
  48. mysql_free_result(res);
  49. return 0;
  50. //goto Exit;
  51. }
  52. //从选取的文件中读取图片数据
  53. int ReadImg(char *filename ,char *buffer) //filename:用来存储 Path+filename buffer:用来存储
  54. {
  55. if (NULL == filename || buffer == NULL)
  56. {
  57. return -1;
  58. }
  59. //打开文件
  60. FILE* fp = fopen(filename, "rb");//rb 以读的方式打开
  61. //判断是否成功打开了文件
  62. if (NULL == fp )
  63. {
  64. printf("Fopen fail! \n");
  65. return -2;
  66. }
  67. //测量文件字节数(偏移量 三板斧 都得要
  68. fseek(fp, 0, SEEK_END);将位置指针移动到文件末尾
  69. int length = ftell(fp); // file size 确定文件的大小
  70. fseek(fp, 0, SEEK_SET);//将位置指针移动到文件开头
  71. int size = fread(buffer, 1,length,fp); //每次读取一个字节 从fp的指向开始 每次读1个字节 存放到buffer中 要执行length次
  72. //判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小
  73. if (size != length)
  74. {
  75. printf("FileRead error ! %d \n",size);
  76. return -3;
  77. }
  78. //关闭文件
  79. fclose(fp);
  80. //返回长度
  81. return size;
  82. }
  83. //数据库中存储图片数据
  84. int MySQL_WriteImg(MYSQL *mysql,char *buffer, int length)
  85. {
  86. if (mysql == NULL || buffer == NULL || length <= 0) return -1;
  87. MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存
  88. int ret = mysql_stmt_prepare(stmt, SQL_INSERT_TB_USER_IMG, strlen(SQL_INSERT_TB_USER_IMG));
  89. if (ret)
  90. {
  91. printf("mysql_stmt_prepare is error ! %s \n",mysql_error(mysql));
  92. return -2;
  93. }
  94. //绑定数据
  95. MYSQL_BIND parme = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用
  96. parme.buffer_type = MYSQL_TYPE_LONG_BLOB;
  97. parme.buffer = NULL;
  98. parme.is_null = 0;
  99. parme.length = NULL;
  100. ret = mysql_stmt_bind_param(stmt,&parme);
  101. if (ret)
  102. {
  103. printf("mysql_stmt_bind_param is error ! %s \n", mysql_error(mysql));
  104. return -3;
  105. }
  106. //发送数据到数据库服务器中
  107. ret = mysql_stmt_send_long_data(stmt, 0, buffer, length);
  108. if (ret)
  109. {
  110. printf("mysql_stmt_send_long_data is error ! %s \n", mysql_error(mysql));
  111. return -4;
  112. }
  113. //存储到表中
  114. ret = mysql_stmt_execute(stmt);
  115. if (ret)
  116. {
  117. printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));
  118. return -5;
  119. }
  120. //以上执行完毕关闭stmt
  121. ret = mysql_stmt_close(stmt);
  122. if (ret)
  123. {
  124. printf("mysql_stmt_close is error ! %s \n", mysql_error(mysql));
  125. return -6;
  126. }
  127. return ret;
  128. }
  129. //从数据库中读取图片资源写入到磁盘
  130. int MySQL_ReadImg(MYSQL *mysql,char * buffer, int length)
  131. {
  132. if (mysql == NULL || buffer == NULL || length <= 0) return -1;
  133. MYSQL_STMT* stmt = mysql_stmt_init(mysql);//初始化数据缓存
  134. //执行语句拿到返回值存储到stmt
  135. int ret = mysql_stmt_prepare(stmt, SQL_SELECT_TB_USER_IMG, strlen(SQL_SELECT_TB_USER_IMG));
  136. if (ret)
  137. {
  138. printf("mysql_stmt_prepare is error ! %s \n", mysql_error(mysql));
  139. return -2;
  140. }
  141. //以下都是数据处理
  142. //绑定结果
  143. MYSQL_BIND result = { 0 }; //用于语句输入和返回值 通常和stmt绑定使用
  144. result.buffer_type = MYSQL_TYPE_LONG_BLOB;
  145. //用于承载返回值的长度
  146. unsigned long total_length = 0;
  147. result.length = &total_length; //整张图片的数据长度
  148. ret = mysql_stmt_bind_result(stmt, &result);
  149. if (ret)
  150. {
  151. printf("mysql_stmt_bind_result is error ! %s \n", mysql_error(mysql));
  152. return -3;
  153. }
  154. //执行语句
  155. ret = mysql_stmt_execute(stmt);
  156. if (ret)
  157. {
  158. printf("mysql_stmt_execute is error ! %s \n", mysql_error(mysql));
  159. return -4;
  160. }
  161. //返回结果
  162. ret = mysql_stmt_store_result(stmt);
  163. if (ret) {
  164. printf("mysql_stmt_store_result : %s\n", mysql_error(mysql));
  165. return -5;
  166. }
  167. //数据显示 取出单行可以不需要外循环
  168. while (1)
  169. {
  170. //mysql_stmt_fetch 抓取返回的数据集:stmt 的下一行数据
  171. ret = mysql_stmt_fetch(stmt);
  172. if (ret != 0 && ret != MYSQL_DATA_TRUNCATED) break; // MYSQL_DATA_TRUNCATED 出现数据截短 块存储分片 \
  173. 当mysql_stmt_fetch返回0时意味着数据读取完毕
  174. int start = 0;
  175. while (start<(int)total_length)
  176. {
  177. result.buffer = buffer + start; //result.buffer和传入的参数buffer使用的是一个内存空间
  178. result.buffer_length = 1; //buffer_length buffer的实际大小也就是每次接受数据的最大长度
  179. mysql_stmt_fetch_column(stmt, &result, 0, start);//mysql_stmt_fetch_column:当前行获取一列数据 s
  180. //stmt:存储结果;
  181. //result:保存返回数据的缓存空间;
  182. //0:因为我们查询的数据列只有一个所以是第0个写0
  183. //start:从什么位置开始的偏移量
  184. start += result.buffer_length; //获取下一个偏移量 也就是当前start代表的偏移量+buffer_length的长度
  185. }
  186. }
  187. //关闭stmt
  188. mysql_stmt_close(stmt);
  189. //返回 数据总长
  190. return total_length;
  191. }
  192. //将图片数据写入磁盘
  193. int WirteImg(char* filename, char* buffer, int length) //写到哪个文件中 写入的数据是哪些 写入的长度是多少
  194. {
  195. if (filename == NULL || buffer == NULL || length <= 0) return -1;
  196. FILE* fp = fopen(filename,"wb"); //wb 以写的方式打开
  197. //判断是否成功打开了文件
  198. if (NULL == fp)
  199. {
  200. printf("Fopen fail! \n");
  201. return -2;
  202. }
  203. int size = fwrite(buffer, 1, length, fp);//每次读取一个字节 从fp的指向存放 每次读1个字节 要执行length次
  204. //判断两者长度是否一致 也就是读出来的数据大小是否等于文件大小
  205. if (size != length)
  206. {
  207. printf("FileWrite error!%d \n", size);
  208. return -3;
  209. }
  210. fclose(fp);
  211. }
  212. int main()
  213. {
  214. //注:mysql的两个接口以返回0作为失败
  215. MYSQL mysql;
  216. if (NULL == mysql_init(&mysql)) //初始化数据库
  217. {
  218. printf("mysql_init :%s \n", mysql_error(&mysql)); //mysql提供了统一的错误值
  219. return -1;
  220. }
  221. //mysql_real_connect返回非0成功
  222. if (!mysql_real_connect(&mysql, yang_db_server_ip,
  223. yang_db_server_username, yang_db_server_password,
  224. yang_db_server_definedb, yang_db_server_port, NULL, 0))//第一个参数是定义的数据库对象 第二个是IP地址 三四是用户名和密码 第五个是默认链接数据库名 第六个是端口号 七八置空
  225. {
  226. printf("mysql_real_connect:%s \n", mysql_error(&mysql));
  227. goto Exit;
  228. }
  229. #if 1
  230. sel(&mysql);
  231. #endif
  232. //读取磁盘的图片资源写入到mysql服务器中
  233. #if 1
  234. printf("case : mysql --> read image and write mysql\n");
  235. char buffer[FILE_IMAGE_LENGTH] = { 0 };
  236. int length = ReadImg("1.jpg", buffer); //图片和代码不在一个文件下用绝对路径,在可以直接写文件名
  237. if (length < 0)
  238. {
  239. printf("length : %d \n", length);
  240. goto Exit;
  241. }
  242. printf("length : %d \n", length);
  243. MySQL_WriteImg(&mysql, buffer, length);
  244. #endif // 1
  245. //读取数据库中的图片资源并写入磁盘
  246. #if 1
  247. printf("case : mysql --> read mysql and write image\n");
  248. char buffers[FILE_IMAGE_LENGTH] = { 0 };
  249. memset(buffers, 0, FILE_IMAGE_LENGTH);
  250. int len = MySQL_ReadImg(&mysql, buffers, FILE_IMAGE_LENGTH);
  251. WirteImg("a.jpg", buffers,len);
  252. #endif
  253. #if 0
  254. //insert----SQL
  255. //mysql_real_query返回0成功
  256. if (mysql_real_query(&mysql, SQL_INSERT_TB_USER, strlen(SQL_INSERT_TB_USER)))
  257. {
  258. printf("mysql_real_query :%s \n ", mysql_error(&mysql));
  259. goto Exit;
  260. }
  261. #endif
  262. #if 0
  263. printf("case : mysql --> delete \n");
  264. //delete----SQL
  265. //mysql_real_query返回0成功
  266. if (mysql_real_query(&mysql, SQL_CALL_PROC_TB_USER, strlen(SQL_CALL_PROC_TB_USER)))
  267. {
  268. printf("mysql_real_query :%s \n ", mysql_error(&mysql));
  269. goto Exit;
  270. }
  271. #endif
  272. #if 1
  273. sel(&mysql);
  274. #endif
  275. Exit:
  276. mysql_close(&mysql);
  277. return 0;
  278. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/800519?site
推荐阅读
相关标签
  

闽ICP备14008679号