如何将SPIFFS文件名赋值给变量?ESP32 TFT图片加载问题
问题
我是编程初学者,这是首次提问。我正在开发ESP32程序,从SPIFFS读取JPEG图片并显示到TFT屏幕上。目前已实现硬编码文件名加载图片,但希望通过getFileName()函数获取文件名传入drawJpeg(),多次修改均编译失败,对File变量及name()的使用存在困惑。代码如下:
#define FS_NO_GLOBALS #include <Arduino.h> #include <FS.h> #include <string.h> #include <iostream> // #ifdef ESP32 #include "SPIFFS.h" // ESP32 only // #endif #include <TFT_eSPI.h> // Hardware-specific library TFT_eSPI tft = TFT_eSPI(); // Invoke custom library // JPEG decoder library #include <JPEGDecoder.h> #include "JPEG_functions.h" // Declaration void getFileName(); void setup() { Serial.begin(115200); delay(10); Serial.printf("\nSerial Debugger active!\n"); // Initialize TFT tft.begin(); tft.setRotation(1); tft.fillScreen(TFT_BLUE); delay(10); // Initialize SPIFFS if (!SPIFFS.begin(true)) { Serial.println("SPIFFS initialisation failed!"); } Serial.println("\nSPIFFS Initialisation Complete.\n"); getFileName(); tft.setRotation(1); tft.fillScreen(TFT_RED); } void loop() { drawJpeg("/001.jpg", 0, 0); delay(2500); drawJpeg("/002.jpg", 0, 0); delay(2500); drawJpeg("/003.jpg", 0, 0); delay(2500); drawJpeg("/004.jpg", 0, 0); delay(2500); drawJpeg("/005.jpg", 0, 0); // 240 x 320 image delay(2500); } void getFileName() { // Open SPIFFS File root = SPIFFS.open("/"); File file = root.openNextFile(); // Print SPIFFS file names while (file) { Serial.print("FILE DETECTED\n"); Serial.print("FILE: "); Serial.println(file.name()); file = root.openNextFile(); } }
解决方案
核心问题说明
File.name()返回的是临时const char*指针,当File对象被销毁(比如循环中重新赋值),该指针会失效,直接传递会导致内存错误。- 原
getFileName()仅打印文件名,未将其存储下来供loop()调用,无法实现动态加载。
修改步骤及代码
- 添加全局容器存储JPEG文件名
在所有#include之后、函数声明之前,添加全局变量来保存筛选后的JPEG文件名:
#include <vector> // 需要包含vector头文件 std::vector<String> jpegFiles; // 存储所有JPEG文件名
- 修改
getFileName()函数,收集并保存JPEG文件名
修改函数逻辑,筛选出JPEG格式文件并保存,同时关闭文件避免资源泄漏:
void getFileName() { File root = SPIFFS.open("/"); File file = root.openNextFile(); while (file) { String fileName = file.name(); // 仅保留JPEG格式文件 if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { jpegFiles.push_back(fileName); Serial.print("已识别JPEG文件: "); Serial.println(fileName); } file.close(); // 关闭当前文件,释放资源 file = root.openNextFile(); } root.close(); // 关闭根目录文件 }
- 修改
loop()函数,动态遍历加载图片
替换硬编码的文件名,遍历存储的JPEG文件列表:
void loop() { if (jpegFiles.empty()) { Serial.println("未找到任何JPEG文件"); delay(1000); return; } // 循环遍历所有JPEG文件并显示 for (const String& fileName : jpegFiles) { drawJpeg(fileName.c_str(), 0, 0); // 将String转为const char*传入drawJpeg delay(2500); } }
关键注意事项
- 必须用
String或字符数组复制file.name()的内容,避免使用临时指针导致的编译/运行错误。 - 遍历文件时记得调用
file.close(),避免ESP32的文件句柄耗尽。 drawJpeg()通常接受const char*类型的路径参数,因此需要用String::c_str()转换格式。
内容的提问来源于stack exchange,提问作者realreject
相关产品推荐
相关产品推荐

