免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 16943 | 回复: 59
打印 上一主题 下一主题

[C] 吐血奉献:C语言实现myql中存取二进制文件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-06 17:10 |只看该作者 |倒序浏览
最近搞mysql,这两天想用C把二进制文件(<64k,大的就存储路径了)存储到数据库里,经过我‘不懈’的搜索,发现NET上有且只有一个版本(php为例的),在C里根本行不通,我先是晕倒,醒了后我再搜索,还是php版本的,我又吐了一口血(之后又吐了好几次)!最后还是在mysql手册里找到了方向,是mysql_real_escape_string给了我光明,好了,不罗嗦了,不然要有矿泉水瓶砸过来了!为了不让其它初学者吐血,我把我的code共享一下,希望大侠们指正,也欢迎鸡蛋和西红柿:m01::m01::m01:

  1. #include <stdio.h>
  2. #include <mysql/mysql.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>

  7. #define host               "localhost"              //mysql server
  8. #define username        "root"
  9. #define password        "root"
  10. #define database         "www"
  11.    
  12. int get_file_size(char *path, off_t *size)
  13. {
  14.         struct stat file_stats;

  15.         if(stat(path, &file_stats))
  16.                 return -1;

  17.         *size = file_stats.st_size;
  18.         return 0;
  19. }
  20. int main(int argc, char *argv[])
  21. {
  22.         char  *filename;
  23.         off_t  size;

  24.         MYSQL            *conn;
  25.         MYSQL_RES    *res_set;
  26.         MYSQL_ROW    row;
  27.         MYSQL_FIELD *field;
  28.         int                   i, flag;
  29.         char                *sql;
  30.         FILE                *fp;
  31.         char                *buf;
  32.         int                    n=0;
  33.         char                *end;
  34.         unsigned long *length;       
  35.        
  36.         if (argc != 2) {
  37.                 printf("Usage: %s srcfile\n", argv[0]);
  38.                 exit(1);
  39.         }

  40.         filename = argv[1];
  41.         if ((get_file_size(filename, &size)) == -1) {
  42.                 perror("get file size" );
  43.                 exit(1);
  44.         }
  45.        
  46.         if ((buf = (char *)malloc(sizeof(char)*(size+1))) == NULL) {
  47.                 perror("malloc buf" );
  48.                 exit(1);
  49.         }

  50.         if ((fp = fopen(filename, "rb" )) == NULL) {
  51.                 perror("fopen file" );
  52.                 exit(1);
  53.         }

  54.         if ((n = fread(buf, 1, size, fp)) < 0) {        //n=*size
  55.                 perror("fread file" );
  56.                 exit(1);
  57.         }

  58.         sql = (char *)malloc(sizeof(char)*n*2+256);        //2n+1+strlen(other sql)
  59.         if (sql == NULL) {
  60.                 perror("malloc sql" );
  61.                 exit(1);
  62.         }

  63.         conn = mysql_init(NULL);
  64.         if (conn == NULL) {
  65.                 printf("init mysql, %s\n", mysql_error(conn));
  66.                 exit(1);
  67.         }

  68.         if ((mysql_real_connect(conn, host, username, password, database, 0, NULL, 0)) == NULL) {
  69.                 printf("connect mysql, %s\n", mysql_error(conn));
  70.                 exit(1);
  71.         }

  72.         strcpy(sql, "insert into www(id, name, file) values(5, 'peter', " );
  73.         end = sql;
  74.         end += strlen(sql);                //point sql tail
  75.         //convert NUL(ASCII 0)、'\n'、'\r'、'\'’、'''、'"'、Control-Z and so on
  76.         *end++ = '\'';
  77.         end += mysql_real_escape_string(conn, end, buf, n);
  78.         *end++ = '\'';
  79.         *end++ = ')';
  80.        
  81.         flag = mysql_real_query(conn, sql, (unsigned int)(end-sql));
  82.         if (flag != 0) {
  83.                 printf("insert failed, %s\n", mysql_error(conn));
  84.                 exit(1);
  85.         }

  86.         if ((mysql_real_query(conn, "SELECT file FROM www where id=5", 31)) != 0) {
  87.                 printf("insert failed, %s\n", mysql_error(conn));
  88.                 exit(1);
  89.         }
  90.         res_set = mysql_store_result(conn);

  91.         fclose(fp);
  92.         fp = NULL;

  93.         fp = fopen("foo.bk", "wb" );
  94.         while ((row = mysql_fetch_row(res_set)) != NULL) {
  95.                 length = mysql_fetch_lengths(res_set);
  96.                 for (i=0; i<mysql_num_fields(res_set); i++) {
  97.                         fwrite(row[0], 1, length[0], fp);
  98.                 }
  99.         }

  100.         fclose(fp);
  101.         mysql_close(conn);
  102.         free(sql);
  103.         sql = NULL;
  104.        
  105.         return 0;
  106. }
  107. //gcc -o mysql_binary mysql_binary.c -lmysqlclient
  108. //usage: ./mysql_binary filename
复制代码

Makefile:

  1. CXX = gcc
  2. LIBS = -lmysqlclient
  3. PRODUCT = mysql_binary
  4. .LIBPATTERNS: lib%.so lib%.a
  5. vpath %   .
  6. vpath %.c src
  7. vpath %.h include

  8. OBJS = mysql_binary.o
  9. $(PRODUCT): $(OBJS)  
  10.         $(CXX) $(OBJS) -o $@ $(LIBS)
  11. .c.o:

  12. .PHONY:clean
  13. clean:
  14.         -rm -f $(OBJS) $(PRODUCT)
复制代码

好了,擦汗!
晕 这么多表情符号,弄一下。
生成的foo.bk文件为源文件的拷贝。

[ 本帖最后由 mike_chen 于 2007-4-13 09:01 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-04-06 17:55 |只看该作者
没有顶的,我的血白吐了,晚上回去吃几个鸡蛋,补补!

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2006-04-06 18:04 |只看该作者
呵呵,鼓励一下!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2006-04-06 18:05 |只看该作者
我顶!
楼主贴代码最好用code功能。

论坛徽章:
0
5 [报告]
发表于 2006-04-06 18:17 |只看该作者
原帖由 lenovo 于 2006-4-6 18:05 发表
我顶!
楼主贴代码最好用code功能。

呵呵 用了,不知道为什么有的地方总对不齐,<tab>键到这里走样了


谢谢版主加精!

论坛徽章:
0
6 [报告]
发表于 2006-04-06 18:20 |只看该作者
人才啊,值得鼓励,能把自己辛辛苦苦作出来的东西分享给大家,值得尊重了

论坛徽章:
0
7 [报告]
发表于 2006-04-06 19:40 |只看该作者
路过误入,潜水太久,顺便支持一个!

论坛徽章:
0
8 [报告]
发表于 2006-04-06 22:13 |只看该作者
不错,支持原创!!!

论坛徽章:
0
9 [报告]
发表于 2006-04-06 23:37 |只看该作者
mark~~

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2006-04-06 23:48 |只看该作者
up!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP