You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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()调用,无法实现动态加载。

修改步骤及代码

  1. 添加全局容器存储JPEG文件名
    在所有#include之后、函数声明之前,添加全局变量来保存筛选后的JPEG文件名:
#include <vector> // 需要包含vector头文件
std::vector<String> jpegFiles; // 存储所有JPEG文件名
  1. 修改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(); // 关闭根目录文件
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:14:56