vc 将文件存入mysql数据库
2008-07-15 11:31
近日公司安排了一个任务,就是做一个在Windows下往linux下的mysql插入文件的工具,如果只是单纯的插入,网上应该有工具可以下载的,但是我没有去找了,自己实现了一个,将开发过程里用到的一些东西记录下来,以后再遇到的话,可以来这里查一查。 与mysql通讯,我选择直接使用mysql的C API,可以非常方便快捷地对Mysql进行操作,还可以轻松地实现跨平台,如果使用ODBC,那么在*nix下时,还得重写一套代码。 要存文件的话,mysql中需要将对应的域设为blob或者longblob类型,如果是其它类型的话,比如TEXT,存进去再取出来可能会丢失数据。Mysql中插入blob,是通过INSERT语句实现的,它将文件的二进制流读出来,然后转义成可识别的ASCII码,这个工作由mysql_real_escape_string函数完成,然后再调用mysql_real_query做插入工作。 需要注意的是,这里必须调用mysql_real_query,mysql的手册中这样描述: You must use mysql_real_query() rather than mysql_query() for queries that contain binary data, because binary data may contain the ‘/0’ character. In addition, mysql_real_query() is faster than mysql_query() because it does not call strlen() on the query string. 讲了这么多了,下面附一个我写的函数例子, 注意这个函数是纯C写的,与C++没有关联: int my_upload_blob(MYSQL* db, const char* filepath, const char* cmd_prev, int prev_len, const char* cmd_next, int next_len) { unsigned long len =0; unsigned long size = 0; char *data = NULL; char *chunk = NULL; char *query = NULL; char *pos = NULL; FILE *fp; fp = fopen(filepath, "rb"); if (NULL == fp) { return ERR_OPEN_FILE; } data = malloc(1000*1024); /* 1M */ chunk = malloc(2*1000*1024+1); /* 2M */ query = malloc(1024*5000); /* 5M */ pos = query; size = fread(data, 1, 1024*1000, fp); size = mysql_real_escape_string(db, chunk, data, size); /* copy sql to query */ len = prev_len; strncpy(query, cmd_prev, len); pos = query + len; /* copy binary file data to query */ *pos++ = '/''; strncpy(pos, chunk, size); pos += size; *pos++ = '/''; /* if next is not null, a comma is needed */ if (cmd_next) { *pos++ = ','; } /* copy sql to query */ len = next_len; strncpy(pos, cmd_next, len); pos += len; /* should call mysql_real_query */ if (0 != mysql_real_query(db, query, pos - query)) { free(data); free(chunk); free(query); fclose(fp); return ERR_MYSQL_QUERY; } free(data); free(chunk); free(query); fclose(fp); return 0; } 另附下载函数: int my_download_blob(MYSQL* db, char* filepath, char* cmd, int field_pos) { unsigned long *lengths; FILE *fp; fp = fopen(filepath, "wb"); if (NULL == fp) { return ERR_OPEN_FILE; } if (0 != mysql_query(db, cmd)) { return ERR_MYSQL_QUERY; } MYSQL_RES* _res = mysql_store_result(db); MYSQL_ROW _row = mysql_fetch_row(_res); if (NULL == _res) { /* add your code here */ } lengths = mysql_fetch_lengths(_res); fwrite(row[field_pos], lengths[field_pos], 1, fp); fclose(fp); mysql_free_result(_res); return 0; } 本blog不转载任何文章,如果你在代码中用到了本blog中的代码,请回复中知会一声。 |