Arduino:SD卡文件按块读取至字符数组再写入的实现难题
解决Arduino SD卡分块文件复制问题(处理不足块大小的剩余字节)
原代码的核心问题
- 变量名错误:
myFile.read()应为oFile.read(),原代码打开的是oFile,此处笔误导致编译失败 - 未定义变量:
cByteAvailable无声明/赋值,剩余字节判断逻辑完全失效 - 错误的字符串终止符:给字节缓冲区加
'\0'会额外写入空字节,破坏原文件内容(尤其是后续处理图片等二进制文件时) - 剩余字节未处理:循环结束后,缓冲区中不足100字节的内容未写入目标文件,导致副本不完整
- 低效逐字节读取:逐字节循环分块,远不如SD库原生的块读取高效
修正后的分块读写代码
#include <SD.h> File oFile; File cFile; const int BUFFER_SIZE = 100; // 后续可直接改为512 char buffer[BUFFER_SIZE]; void setup() { Serial.begin(9600); while (!Serial); // 调试用:等待串口连接 // 初始化SD卡(CS引脚根据硬件调整,这里用引脚4为例) if (!SD.begin(4)) { Serial.println("SD卡初始化失败"); return; } // 打开原文件和目标文件 oFile = SD.open("message.txt", FILE_READ); cFile = SD.open("message2.txt", FILE_WRITE); if (!oFile || !cFile) { Serial.println("文件打开失败"); return; } // 分块读写核心逻辑 size_t bytesRead; // 每次读取最多BUFFER_SIZE字节,返回实际读取的字节数,直到读取完毕 while ((bytesRead = oFile.read(buffer, BUFFER_SIZE)) > 0) { cFile.write(buffer, bytesRead); // 写入实际读取的字节数,自动处理剩余不足块的情况 // 调试输出(可选) Serial.print("处理字节数:"); Serial.println(bytesRead); Serial.write(buffer, bytesRead); // 直接输出字节,避免字符串截断问题 Serial.println(); } // 关闭文件,释放资源 oFile.close(); cFile.close(); Serial.println("文件复制完成"); } void loop() { // 无需循环执行 }
关键改进说明
- 原生块读取:使用
File.read(buffer, size)方法,一次最多读取指定大小的字节,返回实际读取的字节数,代码更简洁高效,无需手动逐字节计数 - 自动处理剩余字节:当文件剩余字节不足BUFFER_SIZE时,
bytesRead会返回实际剩余的字节数,write方法只写入这些字节,完美解决末尾不足块的问题 - 去掉冗余操作:无需用
memset清空缓冲区,下一次读取会直接覆盖旧内容 - 错误检查:添加SD卡初始化和文件打开的错误判断,避免程序无提示崩溃
- 通用兼容性:此逻辑既适用于文本文件,也适用于后续的图片等二进制文件,无需修改即可适配BUFFER_SIZE改为512的需求
内容的提问来源于stack exchange,提问作者acanessa
相关产品推荐
相关产品推荐

