138 lines
4.0 KiB
C
138 lines
4.0 KiB
C
#include "spiffs.h"
|
||
|
||
static const char *TAG = "SPIFFS";
|
||
|
||
/**
|
||
* @brief 初始化并挂载 SPIFFS 文件系统
|
||
* @param base_path 挂载点路径(如 "/spiffs")
|
||
* @return esp_err_t ESP_OK 成功,其他失败
|
||
*/
|
||
esp_err_t spiffs_init(const char *base_path)
|
||
{
|
||
ESP_LOGI(TAG, "正在初始化 SPIFFS...");
|
||
|
||
esp_vfs_spiffs_conf_t conf = {
|
||
.base_path = base_path,
|
||
.partition_label = NULL, // 使用第一个找到的 SPIFFS 分区
|
||
.max_files = 10, // 最大打开文件数
|
||
.format_if_mount_failed = true // 如果挂载失败则格式化
|
||
};
|
||
|
||
// 挂载 SPIFFS 分区
|
||
esp_err_t ret = esp_vfs_spiffs_register(&conf);
|
||
if (ret != ESP_OK)
|
||
{
|
||
if (ret == ESP_FAIL)
|
||
{
|
||
ESP_LOGE(TAG, "挂载 SPIFFS 失败");
|
||
}
|
||
else if (ret == ESP_ERR_NOT_FOUND)
|
||
{
|
||
ESP_LOGE(TAG, "未找到 SPIFFS 分区");
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGE(TAG, "SPIFFS 初始化失败 (%s)", esp_err_to_name(ret));
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
ESP_LOGI(TAG, "SPIFFS 挂载成功,挂载点: %s", base_path);
|
||
|
||
// 获取分区信息
|
||
size_t total = 0, used = 0;
|
||
ret = esp_spiffs_info(NULL, &total, &used);
|
||
if (ret != ESP_OK)
|
||
{
|
||
ESP_LOGE(TAG, "获取 SPIFFS 分区信息失败 (%s)", esp_err_to_name(ret));
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(TAG, "分区大小: 总共 %d KB, 已用 %d KB, 可用 %d KB",
|
||
total / 1024, used / 1024, (total - used) / 1024);
|
||
}
|
||
|
||
return ESP_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief 列出 SPIFFS 文件(安全版本)
|
||
*/
|
||
void list_spiffs_files_safe(const char *base_path)
|
||
{
|
||
ESP_LOGI(TAG, "Listing files in %s:", base_path);
|
||
|
||
DIR *dir = opendir(base_path);
|
||
if (dir == NULL) {
|
||
ESP_LOGE(TAG, "Failed to open directory %s: %s",
|
||
base_path, strerror(errno));
|
||
return;
|
||
}
|
||
|
||
struct dirent *entry;
|
||
int count = 0;
|
||
|
||
while ((entry = readdir(dir)) != NULL) {
|
||
// 跳过 "." 和 ".."
|
||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||
continue;
|
||
}
|
||
|
||
// 方法1:使用固定大小缓冲区(512字节足够)
|
||
char full_path[512];
|
||
int ret = snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->d_name);
|
||
|
||
if (ret < 0) {
|
||
ESP_LOGW(TAG, "Error formatting path for: %s", entry->d_name);
|
||
continue;
|
||
}
|
||
|
||
if ((size_t)ret >= sizeof(full_path)) {
|
||
ESP_LOGW(TAG, "Path truncated for: %s", entry->d_name);
|
||
// 继续处理,但路径可能不完整
|
||
}
|
||
|
||
// 方法2:使用动态分配(如果文件名可能很长)
|
||
// size_t path_len = strlen(base_path) + 1 + strlen(entry->d_name) + 1;
|
||
// char *full_path = malloc(path_len);
|
||
// if (full_path) {
|
||
// snprintf(full_path, path_len, "%s/%s", base_path, entry->d_name);
|
||
// // ... 使用 full_path
|
||
// free(full_path);
|
||
// }
|
||
|
||
struct stat entry_stat;
|
||
if (stat(full_path, &entry_stat) == -1) {
|
||
ESP_LOGW(TAG, " %s - cannot stat: %s",
|
||
entry->d_name, strerror(errno));
|
||
continue;
|
||
}
|
||
|
||
if (S_ISDIR(entry_stat.st_mode)) {
|
||
ESP_LOGI(TAG, " [DIR] %-32s", entry->d_name);
|
||
} else {
|
||
const char *unit = "B";
|
||
double size = (double)entry_stat.st_size;
|
||
|
||
if (size >= 1024.0 * 1024.0) {
|
||
size /= 1024.0 * 1024.0;
|
||
unit = "MB";
|
||
} else if (size >= 1024.0) {
|
||
size /= 1024.0;
|
||
unit = "KB";
|
||
}
|
||
|
||
ESP_LOGI(TAG, " [FILE] %-32s %8.2f %s",
|
||
entry->d_name, size, unit);
|
||
}
|
||
count++;
|
||
}
|
||
|
||
closedir(dir);
|
||
|
||
if (count == 0) {
|
||
ESP_LOGI(TAG, " No files found");
|
||
} else {
|
||
ESP_LOGI(TAG, "Total: %d items", count);
|
||
}
|
||
} |