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中的代码,请回复中知会一声。

 posted on 2011-03-15 16:36  chingliuyu  阅读(712)  评论(0编辑  收藏  举报