Linux下实现MySQL存储和提取图片
来源:互联网 发布:洛必达法则 知乎 编辑:程序博客网 时间:2024/05/09 16:24
前言:
最近正好在项目中接触到MySQL数据库,无聊时候突然想把照片存储到数据库中,这一想法让我不断的查找资料和编写代码的实践和测试下,今天最终在Linux下实现这一功能.
//dbproc.c
/************************************************************* FileName : dbproc.c FileFunc : MySQL数据库操作实现 Version : V0.1 Author : Sunrier Date : 2012-06-23 Descp : Linux下使用C语言访问MySQL函数 *************************************************************/ #include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h> #include <mysql.h>#define DEBUG __FILE__,__LINE__static MYSQL s_my_connection;static int s_iDbconnected = 0; /*数据库连接标志 连接时为1,断开时为0*//*程序调试函数*/void debug(char *pFileName,int iLine,const char *fmt, ...){char szTemp[256];va_list vap;/*memset(szTemp,0,sizeof(szTemp));*/va_start(vap,fmt);fprintf(stderr,"[%s][%d]:",pFileName,iLine);memset(szTemp,0,sizeof(szTemp));vsprintf(szTemp,fmt,vap);va_end(vap);fprintf(stderr,"%s\n",szTemp);fflush(stderr);}/*测试MySQL客户端版本*/void mysql_version( void ) { printf("MySQL client version : %s ! \n",mysql_get_client_info()); } /*登陆MySQL*/int mysql_login(char* pServer,char *pUser,char *pPassword,char *pDataBase){MYSQL *conn_ptr = NULL;int iRetCode = -1;unsigned int uiTimeOut = 7;if( s_iDbconnected )return 0;conn_ptr = mysql_init(&s_my_connection);if( !conn_ptr ){fprintf(stderr,"mysql_init failed ! \n");return EXIT_FAILURE;}iRetCode = mysql_options(&s_my_connection,MYSQL_OPT_CONNECT_TIMEOUT,(const char *)&uiTimeOut);if( iRetCode ){fprintf(stderr,"MySQL Connection is timeout! \n");return EXIT_FAILURE;}conn_ptr = NULL;conn_ptr = mysql_real_connect(&s_my_connection,pServer,pUser,pPassword,pDataBase,0,NULL,0);if( conn_ptr ){printf("MySQL Connection success!\n");s_iDbconnected = 1;}else{fprintf(stderr,"MySQL Connection failed!\n");if( mysql_errno(&s_my_connection) ){fprintf(stderr,"Connection error %d: %s!\n",mysql_errno(&s_my_connection),mysql_error(&s_my_connection));return EXIT_FAILURE;}}return EXIT_SUCCESS;}/*退出MySQL*/void mysql_logout( void ){if( s_iDbconnected )mysql_close(&s_my_connection); /*关闭连接*/ s_iDbconnected = 0 ;}int mysql_proc( void ){return 0;}/*向MySQL数据库中存储图片*/int mysql_store_image(char *pFileName,char *pImageTableName,unsigned char ucIdFlag,int iId){FILE *fp;char szImageName[31];char szImageData[1024*1000];/*图片大小最大不超过1M*/char szStoreImageData[2*1024*1000+1];char szSql[2*1024*1000+1];unsigned long ulReadLength = 0,ulStoreLength = 0;int iRetCode = -1;fp = fopen(pFileName,"rb");if( NULL==fp ){fprintf(stderr,"This file: [ %s ] isn't exsit !\n",pFileName);return EXIT_FAILURE;}memset(szImageData,0,sizeof(szImageData));ulReadLength = fread(szImageData,1,1024*1000,fp);fclose(fp);if( !ulReadLength ){fprintf(stderr,"Read file found error !\n");return EXIT_FAILURE;}printf("ulReadLength = %ld \n",ulReadLength);memset(szImageName,0,sizeof(szImageName));memcpy(szImageName,pFileName,strlen(pFileName));memset(szStoreImageData,0,sizeof(szStoreImageData));ulStoreLength = mysql_real_escape_string(&s_my_connection,szStoreImageData,szImageData,ulReadLength);/*二进制数据可能包含一些特殊字符,这些字符在sql语句中可能会引起一些问题,所以必须转义,理论上每个字符都可能是特殊字符,所以szStoreImageData数组大小是szImageData数组大小的两倍,该函数还会在szStoreImageData数组最后加上结尾符*/printf("ulStoreLength = %ld \n",ulStoreLength);memset(szSql,0,sizeof(szSql));if( 1==ucIdFlag ){sprintf(szSql,"insert into %s(id,name,data) values(%d,'%s','%s')",pImageTableName,iId,szImageName,szStoreImageData);}else{sprintf(szSql,"insert into %s(name,data) values('%s','%s')",pImageTableName,szImageName,szStoreImageData);}iRetCode = mysql_query(&s_my_connection,szSql);if( iRetCode ){fprintf(stderr,"insert error ,sqlcode=[%d] : %s !\n",mysql_errno(&s_my_connection),mysql_error(&s_my_connection));return EXIT_FAILURE;}return EXIT_SUCCESS;}/*向MySQL数据库中存储图片*/int mysql_store_image_ex(char *pFileName,char *pImageTableName,unsigned char ucIdFlag,int iId){FILE *fp;char szImageName[31];char szImageData[1024*1000];/*图片大小最大不超过1M*/char szStoreImageData[2*1024*1000+1];char szSql[2*1024*1000+1];unsigned long ulReadLength = 0,ulStoreLength = 0,ulStoredLength = 0;int iRetCode = -1;fp = fopen(pFileName,"rb");if( NULL==fp ){fprintf(stderr,"This file: [ %s ] isn't exsit !\n",pFileName);return EXIT_FAILURE;}memset(szImageData,0,sizeof(szImageData));ulReadLength = fread(szImageData,1,1024*1000,fp);fclose(fp);if( !ulReadLength ){fprintf(stderr,"Read file found error !\n");return EXIT_FAILURE;}printf("ulReadLength = %ld \n",ulReadLength);memset(szImageName,0,sizeof(szImageName));memcpy(szImageName,pFileName,strlen(pFileName));memset(szStoreImageData,0,sizeof(szStoreImageData));ulStoreLength = mysql_real_escape_string(&s_my_connection,szStoreImageData,szImageData,ulReadLength);/*二进制数据可能包含一些特殊字符,这些字符在sql语句中可能会引起一些问题,所以必须转义,理论上每个字符都可能是特殊字符,所以szStoreImageData数组大小是szImageData数组大小的两倍,该函数还会在szStoreImageData数组最后加上结尾符*/printf("ulStoreLength = %ld \n",ulStoreLength);memset(szSql,0,sizeof(szSql));if( 1==ucIdFlag ){sprintf(szSql,"insert into %s(id,name,data) values(%d,'%s','%s')",pImageTableName,iId,szImageName,szStoreImageData);}else{sprintf(szSql,"insert into %s(name,data) values('%s','%s')",pImageTableName,szImageName,szStoreImageData);}ulStoredLength = strlen(szSql);iRetCode = mysql_real_query(&s_my_connection,szSql,ulStoredLength);printf("ulStoredLength = %ld \n",ulStoredLength);if( iRetCode ){fprintf(stderr,"insert error ,sqlcode=[%d] : %s !\n",mysql_errno(&s_my_connection),mysql_error(&s_my_connection));return EXIT_FAILURE;}return EXIT_SUCCESS;}/*从MySQL数据库提取存储的图片*/int mysql_fetch_image(char *pFileName,char *pImageTableName,unsigned char ucFlag,int iId){FILE *fp; MYSQL_RES *res_ptr = NULL;MYSQL_ROW sqlrow;int iRetCode = -1,iTableRow = 0;char szSql[256];unsigned long *ulLength = NULL;unsigned long ulWriteLength = 0;/*ucFlag = 1 表示指定文件名*/memset(szSql,0,sizeof(szSql));if( 1==ucFlag ){sprintf(szSql,"select data from %s where id = %d",pImageTableName,iId);}else{fprintf(stderr,"This flag [ %d ] found error for the filename ,and you must specify a filename !\n",ucFlag);return EXIT_FAILURE;}fp = fopen(pFileName,"wb");if( NULL==fp ){fprintf(stderr,"This file: [ %s ] isn't exsit !\n",pFileName);return EXIT_FAILURE;}iRetCode = mysql_query(&s_my_connection,szSql);/*执行SQL语句*/ if( iRetCode ) { fprintf(stderr,"Select error %d: %s !\n",mysql_errno(&s_my_connection),mysql_error(&s_my_connection));/*打印错误处理具体信息*/ return EXIT_FAILURE; } res_ptr = mysql_store_result(&s_my_connection);/*集合*/ if( res_ptr ) { iTableRow = mysql_num_rows(res_ptr);/*行*/ if( iTableRow==0 )/*表示查询没有结果*/ { fclose(fp);fprintf(stderr,"Select data from %s where id = [ %d ] , result is null !\n",pImageTableName,iId); return EXIT_FAILURE; } sqlrow = mysql_fetch_row(res_ptr); ulLength = mysql_fetch_lengths(res_ptr); printf("ulFetchedLength: %ld\n",ulLength[0]);/*从数据库中提取的数据信息长度*/mysql_free_result(res_ptr);/*完成对数据的所有操作后,调用此函数来让MySQL库清理它分配的对象*/ulWriteLength = fwrite(sqlrow[0],1,ulLength[0],fp);if( ulWriteLength==0 ){fclose(fp);fprintf(stderr,"Write file found error !\n");return EXIT_FAILURE;}printf("ulWriteLength = %ld \n",ulWriteLength);/*写入文件的数据信息长度*/}else { fclose(fp);fprintf(stderr,"Select result is null !\n"); return EXIT_FAILURE; } fclose(fp);return EXIT_SUCCESS;}/*从MySQL数据库提取存储的图片*/int mysql_fetch_image_ex(char *pFileName,char *pImageTableName,unsigned char ucFlag,int iId){FILE *fp; MYSQL_RES *res_ptr = NULL;MYSQL_ROW sqlrow;int iRetCode = -1,iTableRow = 0;char szSql[256];unsigned long *ulLength = NULL;unsigned long ulWriteLength = 0;memset(szSql,0,sizeof(szSql));/*ucFlag = 2 表示取数据库表中的信息文件名*/if( 2==ucFlag ){sprintf(szSql,"select data,name from %s where id = %d",pImageTableName,iId);}else{fprintf(stderr,"This flag [ %d ] found error for the filename ,and you needn't specify a filename !\n",ucFlag);return EXIT_FAILURE;}iRetCode = mysql_query(&s_my_connection,szSql);/*执行SQL语句*/ if( iRetCode ) { fprintf(stderr,"Select error %d: %s !\n",mysql_errno(&s_my_connection),mysql_error(&s_my_connection));/*打印错误处理具体信息*/ return EXIT_FAILURE; } res_ptr = mysql_store_result(&s_my_connection);/*集合*/ if( res_ptr ) { iTableRow = mysql_num_rows(res_ptr);/*行*/ if( iTableRow==0 )/*表示查询没有结果*/ { fclose(fp);fprintf(stderr,"Select data,name from %s where id = [ %d ] , result is null !\n",pImageTableName,iId); return EXIT_FAILURE; } sqlrow = mysql_fetch_row(res_ptr); ulLength = mysql_fetch_lengths(res_ptr); sscanf(sqlrow[1],"%s",pFileName);/*从数据库中取文件名*/ printf("ulFetchedLength: %ld\n",ulLength[0]);mysql_free_result(res_ptr);/*完成对数据的所有操作后,调用此函数来让MySQL库清理它分配的对象*/fp = fopen(pFileName,"wb");if( NULL==fp ){fprintf(stderr,"This file: [ %s ] isn't exsit !\n",pFileName);return EXIT_FAILURE;}ulWriteLength = fwrite(sqlrow[0],1,ulLength[0],fp);if( ulWriteLength==0 ){fclose(fp);fprintf(stderr,"Write file found error !\n");return EXIT_FAILURE;}printf("ulWriteLength = %ld \n",ulWriteLength);}else { fclose(fp);fprintf(stderr,"Select result is null !\n"); return EXIT_FAILURE; } fclose(fp);return EXIT_SUCCESS;}
//store.c
/*********************************************************************** FileName : store.c FileFunc : 把图片存储到MySQL数据库中操作测试(图片大小最大不超过1M) Version : V0.1 Author : Sunrier Date : 2012-06-23 Descp : Linux下使用C语言访问MySQL函数 ************************************************************************/#include <stdio.h>int main(int argc,char *argv[]){ char szServer[20] = "localhost"; /*127.0.0.1*/ char szUser[20] = "Sunrier"; char szPassword[20] = "redhat"; char szDatabase[20] = "test"; char szFileName[30],szTableName[30];unsigned char ucIdFlag = 0;/*手动插入ID标志*/int iRetCode = -1,iId =0; iRetCode = mysql_login(szServer,szUser,szPassword,szDatabase); if( iRetCode ){return 1;}memset(szFileName,0,sizeof(szFileName));memset(szTableName,0,sizeof(szTableName));strcpy(szFileName,"Sunrier.jpg");strcpy(szTableName,"images");ucIdFlag = 0;iId =1;/*iRetCode = mysql_store_image( szFileName,szTableName,ucIdFlag,iId );*/iRetCode = mysql_store_image_ex( szFileName,szTableName,ucIdFlag,iId );if( !iRetCode ){fprintf(stderr,"Image has been stored in the database !\n");}mysql_logout();return 0;}
//fetch.c
/********************************************************************** FileName : fetch.c FileFunc : 从MySQL数据库中提取图片操作测试(图片大小最大不超过1M) Version : V0.1 Author : Sunrier Date : 2012-06-23 Descp : Linux下使用C语言访问MySQL函数 ***********************************************************************/#include <stdio.h>int main(int argc,char *argv[]){int iRetCode = -1; char szServer[20] = "localhost"; char szUser[20] = "Sunrier"; char szPassword[20] = "redhat"; char szDatabase[20] = "test"; char szFileName[30],szTableName[30]; unsigned char ucFlag = 0; int iId = 0; iRetCode = mysql_login(szServer,szUser,szPassword,szDatabase); if( iRetCode ){return 1;}ucFlag = 2;iId = 9;memset(szFileName,0,sizeof(szFileName));memset(szTableName,0,sizeof(szTableName));strcpy(szFileName,"Sunrier.jpg");strcpy(szTableName,"images");/*iRetCode = mysql_fetch_image(szFileName,szTableName,ucFlag,iId);*/iRetCode = mysql_fetch_image_ex(szFileName,szTableName,ucFlag,iId);if( !iRetCode ){fprintf(stderr,"Image has been fetched from the database !\n");}mysql_logout();return 0;}
//makefile
#makefileOBJS = store fetch all:$(OBJS) CFLAGS = -O -w -ansi #CFLAGS = -O -Wall -ansi CC = gcc $(CFLAGS)MYSQLINCPATH = -I/usr/include/mysql MYSQLLIBPATH = -L/usr/lib/mysql MYSQLLIB = -lmysqlclient -lz -lmstore:store.c dbproc.c @$(CC) $(MYSQLINCPATH) $(MYSQLLIBPATH) -o $@ $? $(MYSQLLIB)fetch:fetch.c dbproc.c @$(CC) $(MYSQLINCPATH) $(MYSQLLIBPATH) -o $@ $? $(MYSQLLIB)clean:@ls | grep -v ^makefile$$ | grep -v [.]c$$ | grep -v [.]h$$ | grep -v [.]sql$$ | grep -v [.]jpg$$ | grep -v [.]txt$$ | xargs rm -rf#makefile
//images.sql
drop database if exists test; create database test; use test; create table images ( id integer auto_increment not null primary key, name varchar(30) not null, data mediumblob not null); -- )engine=innodb charset=gb2312; -- 指定引擎和编码方式-- 图片是二进制数据,mysql有种特殊的数据类型,用来存储二进制数据,叫做BLOB(Binary Large Ojbect)
- Linux下实现MySQL存储和提取图片
- linux mysql图片的存储与提取
- linux下c语言实现图片的socket传输和数据库的存储
- linux下c语言实现图片的socket传输和数据库的存储
- linux 环境下 c语言实现mysql数据库图片的存储以及多数据库直接的转存
- linux 环境下 c语言实现mysql数据库图片的存储以及多数据库直接的转存
- mysql存储和读取图片
- MySQL存储文本和图片
- Linux下使用ffmpeg从视频提取图片
- Beyond Compare 3在windows和linux下实现提取增量包
- linux下opencv读取图片并存储到mysql数据库中
- linux环境下实现图片的读取和显示
- 存储数据库图片,=>提取数据库图片
- php存储和显示图片【MySQL】
- LINUX下更改MYSQL的存储目录
- linux下更改MySQL数据库存储路径
- Linux下Mysql更改数据存储路径
- Linux下修改MySQL默认存储引擎
- 创建锁文件
- C++ 申请二维数组
- 协调锁文件
- Discuz!7.2 common.inc.php 学习
- C++ 类的静态成员详细讲解
- Linux下实现MySQL存储和提取图片
- QT中提取汉字首字母-方法一
- n后问题之二
- 多线程下的C++ 单例模式
- 如何使用installshield进行程序打包发布
- Android Bundle类
- windows 下socket recv 阻塞接收速度慢--send 阻塞发送慢
- 黑马程序员_学习日记52_622三层项目(MD5、NPOI)
- Komodo IDE 7.0.2 Debug UTF-8 Python 文档的Bug