Mysql实战——图片读写
内容介绍Github - C语言实现MySQL图片读写这篇博客的内容是手把手带你实现一个基于C的MySQL数据库连接组件一般用于节点服务器NS中操作图片的读写。主要思路是先用C语言mysql.h搭建起基本数据读写的功能然后将图片文件转化为二进制数据并且分段发送从而实现读写功能。准备工作配置好MySQL尤其是和读写权限有关的配置C语言编程工具链gcc等MySQL与C的连接器 — libmysqlclient-dev第一部分二进制数据读写一、打印下面这个函数实现了打印我们的需要的表当中的所有数据。intneil_mysql_select(MYSQL*handle){if(mysql_real_query(handle,SQL_SELECT_TBL_USER,strlen(SQL_SELECT_TBL_USER))){printf(mysql_real_query: %s\n,mysql_error(handle));}MYSQL_RES*resmysql_store_result(handle);if(resNULL){printf(mysql_real_query: %s\n,mysql_error(handle));return-2;}introwsmysql_num_rows(res);printf(rows: %d\n,rows);intfieldsmysql_num_fields(res);printf(fields: %d\n,fields);//取出并且显示结果MYSQL_ROW row;while((rowmysql_fetch_row(res))){inti0;for(i0;ifields;i){printf(%s\t,row[i]);}printf(\n);}mysql_free_result(res);return0;技术阐释上面实现的函数中传递了一个特别的参数叫做handle名字叫做数据库连接句柄。有了它我们才可以从NS连接到数据库并且进行我们想要的操作并且当操作不成功的时候他可以通过mysql_error(handle)返回错误值。第一个涉及到的mysql函数就是mysql_real_query()这个函数可用于实现SQL查询它接受handle和我们所要执行的SQl查询语句还有长度作为参数。之后我们就会看到为了实现SQL还有一个不同的办法 叫做预处理语句。第13行和16行的这两个函数分别是为了获取行和列的数目。代码第21行这个while循环就是不断地从我们想要的表中读取数据行并且显示结果。mysql_free_result(res)用于释放我们查询所占用的内存空间res。比较值的说的是这个res是我们在第7行创建的用于存储我们查询所得的结果。二、写入下面这一个函数实现了二进制数据的写入。intmysql_write(MYSQL*handle,char*buffer,intlength){if(handleNULL||bufferNULL||length0)return-1;//statementMYSQL_STMT*stmtmysql_stmt_init(handle);intretmysql_stmt_prepare(stmt,SQL_INSERT_IMG_USER,strlen(SQL_INSERT_IMG_USER));if(ret){printf(mysql_stmt_prepar: %s\n,mysql_error(handle));return-2;}MYSQL_BIND param{0};param.buffer_typeMYSQL_TYPE_LONG_BLOB;param.bufferNULL;param.is_null0;param.lengthNULL;retmysql_stmt_bind_param(stmt,param);if(ret){printf(mysql_stmt_bind_param: %s\n,mysql_error(handle));return-3;}//分段将数据发到服务器retmysql_stmt_send_long_data(stmt,0,buffer,length);if(ret){printf(mysql_stmt_send_long_data: %s\n,mysql_error(handle));return-4;}//执行插入到服务器里retmysql_stmt_execute(stmt);if(ret){printf(mysql_stmt_execute: %s\n,mysql_error(handle));return-5;}//关闭retmysql_stmt_close(stmt);if(ret){printf(mysql_stmt_close: %s\n,mysql_error(handle));return-6;}returnret;}技术阐释同样是为了实现SQL语句与之前说过的mysql_real_query相对在以上代码的第6行有一个比较特别的预处理语句句柄的定义—statment预处理语句使用场景安全性有效防止注入攻击高性能重复的查询亦只需要一次编译二进制数据更好支持大二进制数据类型BLOB使用预处理语句可以减少输入的风险并且减少网络传递负担。并且因为这些优点预处理语句更加频繁的出现在实际使用当中。我们之前使用的mysql_real_query实现简单便于调试比较适合一次性的查询比如我们之前查完就释放掉了内存空间。SQL当中实现插入的语句当然是insert我们在Mysql.c的最开始使用#define定义了它#define SQL_INSERT_IMG_USER insert tbl_user(u_name, u_gender, u_img) value(Alice, female, ?);和其他SQL语句一样我们这样定义是为了方便在下面的代码当中引用。值得注意的是对于u_img这个列而言我们想要插入的数据是图片可是图片并不是一个普通的字符串数据图片数据的大小非常大回想之前我们提到过的办法—将他转化为二进制文件分段发送这就是我们上面这个函数的思路。以上代码的第1317行定义了一个MYSQL_BIND这是为了提前告诉服务器所需要传递参数的类型。因为我们在传递参数的时候使用的是SQL_INSERT_IMG_USER insert tbl_user(u_name, u_gender, u_img) value(Alice, female, ?);而最后面这个?是需要bind的内容。1317行的作用依次为MYSQL_BIND参数说明buffer_type MYSQL_TYPE_LONG_BLOB- 指定参数为二进制大对象类型buffer NULL- 不直接提供数据缓冲区使用分段发送is_null 0- 明确表示该参数不是NULL值length NULL- 长度信息将在mysql_stmt_send_long_data中提供之后的代码就是将预处理的语句statement执行即分段发送二进制数据完成后关闭statement。三、读出以下函数实现了二进制数据的读出整体来看结构和之前的二进制数据写入差不多值得注意的是38行的while1是为了处理多行数据而其中的内层循环是为了从服务器接收分段的数据进入buffer并且验证数据是否有丢失MYSQL_DATA_TRUNCATED//从数据库中读取出来intmysql_read(MYSQL*handle,char*buffer,intlength){if(handleNULL||bufferNULL||length0)return-1;MYSQL_STMT*stmtmysql_stmt_init(handle);intretmysql_stmt_prepare(stmt,SQL_SELECT_IMG_USER,strlen(SQL_SELECT_IMG_USER));if(ret){printf(mysql_stmt_prepar: %s\n,mysql_error(handle));return-2;}MYSQL_BIND result{0};result.buffer_typeMYSQL_TYPE_LONG_BLOB;unsignedlongtotal_length0;result.lengthtotal_length;retmysql_stmt_bind_result(stmt,result);if(ret){printf(mysql_stmt_bind_result: %s\n,mysql_error(handle));return-3;}retmysql_stmt_execute(stmt);if(ret){printf(mysql_stmt_execute: %s\n,mysql_error(handle));return-4;}retmysql_stmt_store_result(stmt);if(ret){printf(mysql_stmt_store_result: %s\n,mysql_error(handle));return-5;}//多个数据while(1){retmysql_stmt_fetch(stmt);if(ret!0ret!MYSQL_DATA_TRUNCATED){break;}intstart0;//内层循环while(start(int)total_length){result.bufferbufferstart;//结果集的buffer和存储图片的buffer是同一个result.buffer_length1;mysql_stmt_fetch_column(stmt,result,0,start);startresult.buffer_length;}}mysql_stmt_close(stmt);returntotal_length;}第二部分图片读写下面的目标是提供一个接口用于在主函数main当中调用可以直接操作我们想要的图片文件。一、图片写入intread_image(char*filename,char*buffer){if(filenameNULL||bufferNULL)return-1;FILE*fpfopen(filename,rb);//fp指向文件的开头if(fpNULL){printf(fopen failed\n);return-2;}//file size//下面这个函数将fp指向末尾fseek(fp,0,SEEK_END);intlengthftell(fp);//偏移量fseek(fp,0,SEEK_SET);intsizefread(buffer,1,length,fp);if(size!length){printf(fread failed:%d\n,size);return-3;}fclose(fp);returnsize;}技术阐释以上函数的作用就是从filename这个路径中获取我们想要的文件并将其导入到buffer当中然后我们之前实现的二进制数据处理函数就可以顺利地从buffer当中找到需要发送到Mysql服务器的二进制图片数据。你可能注意到了从图片格式到二进制数据流这个转换的过程究竟是如何完成的—答案是fopen因为我们指定了一个fopen中的第二个参数为“rb”r代表read only只读b代表二进制如果不指定b这个参数则默认使用文本模式导入一定要注意的是图片格式一定不可以用文本模式导入这会导致一些严重的格式问题比如说换行符的转换。文件模式说明rb- 二进制只读模式图片读取wb- 二进制只写模式会清空原文件wb- 二进制读写模式会清空原文件对于图片保存使用wb更为合适二、图片读取几乎和图片写入对称不多赘述。intwrite_image(char*filename,char*buffer,intlength){if(filenameNULL||bufferNULL||length0)return-1;FILE*fpfopen(filename,wb);//fp指向文件的开头if(fpNULL){printf(fopen failed\n);return-2;}intsizefwrite(buffer,1,length,fp);if(size!length){printf(fwrite failed: %d\n,size);return-3;}fclose(fp);returnsize;}

相关新闻

Linux宝塔面板部署与常见问题解决方案

Linux宝塔面板部署与常见问题解决方案

1. Linux环境下宝塔面板部署常见问题全解析作为国内最受欢迎的服务器管理面板之一,宝塔以其直观的操作界面和丰富的功能模块深受开发者喜爱。但在Linux系统上的实际部署过程中,不同发行版、环境配置和网络状况都会导致各种"拦路虎"。结合我多年…

2026/8/10 8:00:56 阅读更多 →
SpringBoot+Vue学生宿舍管理系统开发实战

SpringBoot+Vue学生宿舍管理系统开发实战

1. 项目概述:基于SpringBootVue的学生宿舍管理系统开发实录 这个学生宿舍管理系统项目采用了当下企业级开发中最流行的前后端分离架构。前端使用Vue.js构建响应式用户界面,后端基于SpringBoot框架提供RESTful API服务,数据库层则通过MyBatis实…

2026/8/10 7:59:55 阅读更多 →
基于历史行政区划的现代经济数据模拟分析:以河南为例

基于历史行政区划的现代经济数据模拟分析:以河南为例

这次我们来看一个基于历史区划数据的经济模拟分析项目。它不是一个软件工具或AI模型,而是一个结合历史地理、行政区划和现代经济数据的计算推演框架。核心思路是:假设将当前河南省的行政区划恢复到清朝时期的府、州、厅格局,然后基于各市县的…

2026/8/10 7:59:55 阅读更多 →

最新新闻

YOLOv8网络结构详解

YOLOv8网络结构详解

深入浅出 YOLOv8 网络结构:一张图看懂目标检测三件套(Backbone / Neck / Head)摘要:本文面向目标检测入门者,系统拆解 YOLOv8 的整体架构。从"为什么选 YOLOv8"谈起,逐层讲清 Backbone&#xff0…

2026/8/10 8:57:51 阅读更多 →
基于FPGA的DDS信号发生器设计,生成频率可调的正弦波、三角波、锯齿波和方波

基于FPGA的DDS信号发生器设计,生成频率可调的正弦波、三角波、锯齿波和方波

一、需求概述采用EGo1 FPGA开发板,基于DDS原理,通过拨码开关选择输出的波形为正弦波(2’b00)、三角波(2’b01)、锯齿波(2’b10)或者矩形波(2’b11)&#xff0…

2026/8/10 8:57:51 阅读更多 →
华为交换机VLAN与Trunk配置实战指南

华为交换机VLAN与Trunk配置实战指南

1. 实验背景与核心目标 在中小型网络架构中,VLAN(虚拟局域网)技术是解决广播风暴和提高网络安全性的关键手段。本次实验通过两台交换机的级联配置,模拟企业办公网中常见的跨设备VLAN划分场景。不同于单台交换机的VLAN实验&#xf…

2026/8/10 8:57:51 阅读更多 →
3步快速解密网易云音乐NCM文件:ncmdump免费工具终极指南

3步快速解密网易云音乐NCM文件:ncmdump免费工具终极指南

3步快速解密网易云音乐NCM文件:ncmdump免费工具终极指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的加密NCM格式音乐文件无法在其他播放器播放而烦恼吗?ncmdump解密工具是你需要的…

2026/8/10 8:57:51 阅读更多 →
Windows系统R与RStudio安装配置全攻略:3分钟搭建数据分析环境

Windows系统R与RStudio安装配置全攻略:3分钟搭建数据分析环境

这次我们来看一个R语言和RStudio的安装配置教程。对于数据分析、统计建模和可视化的初学者或需要快速搭建环境的开发者来说,R语言和RStudio的组合是绕不开的起点。很多人卡在第一步:官网下载慢、安装路径选择困难、RStudio找不到R解释器、中文环境乱码。…

2026/8/10 8:57:51 阅读更多 →
快洋淘指纹浏览器

快洋淘指纹浏览器

链接:https://pan.quark.cn/s/3acf9497f557多开浏览器窗口、多登账号,防止窗口间产生关联、防止封号,每个窗口可以模拟独立的电脑信息,模拟不同的IP地址,使得相互间完全环境独立、隔离,避免关联封号&#x…

2026/8/10 8:56:50 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →