Alle Dateinamen aus LittleFS Directory bekommen (Schnell)

#include <WiFi.h>
#include <LITTLEFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <queue>
#include <vector>
#include <ArduinoJson.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <set>
#include <sstream>
#include "class.h"

#define FORMAT_LITTLEFS_IF_FAILED false
#define RXD2 16
#define TXD2 17
#define RXD1 36
#define TXD1 39

#define DEBUG // comment to not run debug
// #define DEBUGPCB // comment to not run debugpcb

#ifndef DEBUG
#define DEBUG_BEGIN(x)
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(x, y)
#else
#ifdef DEBUGPCB
#define DEBUG_BEGIN(baud, config, rxdpin, txdpin) Serial1.begin(baud, config, rxdpin, txdpin)
#define DEBUG_PRINT(x) Serial1.print(x)
#define DEBUG_PRINTLN(x) Serial1.println(x)
#define DEBUG_PRINTF(...) Serial1.printf(__VA_ARGS__)
#else
#define DEBUG_BEGIN(baud, config, rxdpin, txdpin) Serial.begin(baud)
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_PRINTF(...) Serial.printf(__VA_ARGS__)
#endif
#endif

// Constants
const int http_port = 80;
const int led_pin = 2;

// Globals
AsyncWebServer server(http_port);
WebSocketsServer webSocket = WebSocketsServer(81);

// Gcode Queue
std::queue<std::string> gcodeQueue;

// Writing Queue
std::queue<String> writingQueue;

bool waitingForOk = false;

/***********************************************************
   Functions
*/

// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num,
                      WStype_t type,
                      uint8_t *payload,
                      size_t length)
{

  // Figure out the type of WebSocket event
  switch (type)
  {

  // Client has disconnected
  case WStype_DISCONNECTED:
    DEBUG_PRINTF("[%u] Disconnected!\n", client_num);
    if (client_num == 0)
    {
      digitalWrite(led_pin, LOW);
    }

    break;

  // New client has connected
  case WStype_CONNECTED:
  {
    IPAddress ip = webSocket.remoteIP(client_num);
    DEBUG_PRINTF("[%u] Connection from %s\n", client_num, ip.toString().c_str());
    if (client_num == 0)
    {
      // main client connected
      // Get the config.json file
      File configjson = LITTLEFS.open("/config/config.json", "r");
      if (!configjson)
      {
        DEBUG_PRINTLN("Failed to open config.json");
        return;
      }

      // Parse the JSON file
      StaticJsonDocument<512> doc;
      DeserializationError error = deserializeJson(doc, configjson);

      // Close the file as soon as you're done with it
      configjson.close();

      if (error)
      {
        DEBUG_PRINTLN("Failed to parse config.json");
        return;
      }

      // Get the "turnoffboardled" boolean from the config.json file
      bool turnoffboardled = doc["turnoffboardled"];

      if (!turnoffboardled)
      {
        // main client connected and "turnoffboardled" is false
        digitalWrite(led_pin, HIGH);
      }
    }
  }
  break;

  // For everything else: do nothing
  case WStype_TEXT:
    DEBUG_PRINTF("[%u] Received text: %s\n", client_num, payload);
    if (strcmp((char *)payload, "LEDON") == 0)
    {
      digitalWrite(led_pin, HIGH);
    }
    else if (strcmp((char *)payload, "LEDOFF") == 0)
    {
      digitalWrite(led_pin, LOW);
    }
    break;
  case WStype_BIN:
  case WStype_ERROR:
  case WStype_FRAGMENT_TEXT_START:
  case WStype_FRAGMENT_BIN_START:
  case WStype_FRAGMENT:
  case WStype_FRAGMENT_FIN:
  default:
    break;
  }
}

// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request)
{
  IPAddress remote_ip = request->client()->remoteIP();
  DEBUG_PRINTLN("[" + remote_ip.toString() +
                "] HTTP GET request of " + request->url());
  request->send(404, "text/plain", "Not found");
}

/***********************************************************
   Main
*/

void ListAllFilesInDir(String directory)
{
  File root = LITTLEFS.open(directory);
  if (!root)
  {
    DEBUG_PRINTLN("Failed to open directory");
    return;
  }

  if (!root.isDirectory())
  {
    DEBUG_PRINTLN("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file)
  {
    if (file.isDirectory())
    {
      DEBUG_PRINT("DIR : ");
      DEBUG_PRINTLN(file.name());
    }
    else
    {
      DEBUG_PRINT("FILE: ");
      DEBUG_PRINTLN(file.name());
    }
    file = root.openNextFile();
  }
}

void setup()
{

  // Set LED pin as output
  pinMode(led_pin, OUTPUT);

  // Start debug port if DEBUG is defined and Serial1 if DEBUGPCB is defined else Serial
  DEBUG_BEGIN(115200, SERIAL_8N1, RXD1, TXD1);
  // Start Serial2 port
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);

  // Make sure we can read the file system
  if (!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED))
  {
    DEBUG_PRINTLN("Error mounting SPIFFS");
    return;
  }

  int tBytes = LITTLEFS.totalBytes();
  int uBytes = LITTLEFS.usedBytes();
  DEBUG_PRINTLN("File system info");
  DEBUG_PRINT("Total bytes: ");
  DEBUG_PRINTLN(tBytes);
  DEBUG_PRINT("Used bytes: ");
  DEBUG_PRINTLN(uBytes);

  // Get the Network name and password
  File networkjson = LITTLEFS.open("/config/config.json", "r");
  if (!networkjson || networkjson.isDirectory())
  {
    DEBUG_PRINTLN("Failed to open config.json");
    return;
  }

  // Parse the JSON file
  StaticJsonDocument<512> doc;
  DeserializationError error = deserializeJson(doc, networkjson);

  // Close the file as soon as you're done with it
  networkjson.close();

  if (error)
  {
    DEBUG_PRINTLN("Failed to parse config.json");
    return;
  }

  // Get network name and password
  const char *networkname = doc["networkname"];
  const char *networkpassword = doc["networkpassword"];

  DEBUG_PRINTLN("Network name: " + String(networkname));
  DEBUG_PRINTLN("Network password: " + String(networkpassword));

  // Start access point
  WiFi.softAP(networkname, networkpassword);

  // Print our IP address
  DEBUG_PRINTLN();
  DEBUG_PRINTLN("AP running");
  DEBUG_PRINT("My IP address: ");
  DEBUG_PRINTLN(WiFi.softAPIP());

  server.serveStatic("/", LITTLEFS, "/");

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            {
        AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/index.html", "text/html");
        response->addHeader("Content-Encoding", "gzip");
        request->send(response); });

  // Handle file delete
  server.on("/delete", HTTP_DELETE, [](AsyncWebServerRequest *request)
            {
    if (request->hasParam("filename")) { // if the request has a parameter named "filename"
        String filename = request->getParam("filename")->value(); // get the value of the "filename" parameter
        if (LITTLEFS.remove("/" + filename)) { // attempt to delete the file
            request->send(200, "text/plain", "Successfull deleted file: " + filename); // if successful, send a 200 OK response
            DEBUG_PRINTLN("Deleted file: " + filename);
        } else {
            request->send(500, "text/plain", "Failed to delete file"); // if unsuccessful, send a 500 Internal Server Error response
        }
    } else {
        request->send(400, "text/plain", "Bad request"); // if the request does not have a "filename" parameter, send a 400 Bad Request response
    } });

  // Handle GET request for file list
  server.on("/files", HTTP_GET, [](AsyncWebServerRequest *request)
            {
    if (request->hasParam("directory")) {
        String directory = request->getParam("directory")->value();
        ListAllFilesInDir(directory);
        request->send(200, "text/plain", "");
    } else {
        request->send(400, "text/plain", "Bad request");
    } });

  // Handle requests for pages that do not exist
  server.onNotFound(onPageNotFound);

  // Start web server
  server.begin();

  // Start WebSocket server and assign callback
  webSocket.begin();

  // enable heartbeat for websocket
  webSocket.enableHeartbeat(15000, 3000, 2);

  webSocket.onEvent(onWebSocketEvent);
}

void loop()
{
  webSocket.loop();
}

Aktuell nutze ich ListAllFilesInDir um mir die Dateinamen aus der Directory anzeigen zu lassen, ist aber sehr langsam bei vielen Dateien. Gibt es eine andere Möglichkeit das deutlich schneller zu machen? LG

Schau mal bei Fips rein.
Benutzt Du Unterverzeichnisse? Wie/wohin erfolgt die Ausgabe?
Was verstehst Du unter langsam und was unter vielen Dateien?

Gruß Tommy

Hi, also so um 72 Dateien Anzeigen zu lassen braucht er um die 5 sekunden und zieht auch schon ganz schön am HEAP MEMORY

Die Ausgabe erfolgt erstmal nur in die Konsole und nein keine Unterverzeichnisse

Ist halt kein Fileserver :wink:
Ich habe bisher höchstens 5 File drauf und da spielt die Geschwindigkeit keine Rolle.

Gruß Tommy

Hmm, ja ist mir klar das dass kein Fileserver ist aber trotzdem die Dateien sind ja klein, aber kann man das nicht lösen?

Die Dateigröße ist fürs Directory-Listing völlig uninteressant.
Probier mal die Variante von Fips aus, erst alles in eine Liste zu schreiben und die dann auszugeben. Evtl. steht Dir die Ausgabe auf der Zeitlinie.

Gruß Tommy

Hatte ich auch schon ausprobiert bleibt gleich schnell

Denkst du eine Idee wäre es die Referenz zu den Dateien in einer seperaten Liste abzuspeichern also eine Datei die alle dateien kennt...

Bisher sind wir noch nicht mal bei Dateien, die die Files speichern.
Schreibe doch erst mal, was das werden soll.

Gruß Tommy

Also ich muss halt mengen an Dateien abspeichern in einer Directory und wenn der Client sich
an den Webserver verbindet requested er halt die Dateien in der Directory und das können halt viele sein, deswegen brauche ich was schnelles also es geht mir nur um die Dateinamen

openNextFile (compatibiity method, not recommended for new code)

Directory object (Dir)
The purpose of Dir object is to iterate over files inside a directory. It provides multiple access methods.

The following example shows how it should be used:

Dir dir = SPIFFS.openDir("/data");
// or Dir dir = LittleFS.openDir("/data");
while (dir.next()) {
    Serial.print(dir.fileName());
    if(dir.fileSize()) {
        File f = dir.openFile("r");
        Serial.println(f.size());
    }
}

Aus Filesystem — ESP8266 Arduino Core 3.1.2-21-ga348833 documentation

hey aber Dir ist bei mir nicht möglich zu nutzen und .openDir habe ich auch nicht bei LittleFS

Laut Doku sollte das gehen. Welchen µC hast du?

den ESP32 WROOM E32 4MB

genau das hatte ich auch gefunden dann aber aufgegeben weil ich das nicht nutzen konnte

ich benutze die LITTLEFS variante nicht die LittleFS

Warum nutzt Du nicht die originale LittleFS aus dem ESP-Core?
Welche Lib ist das, die Du benutzt? (Link bitte)

Gruß Tommy

Hmm, werde ich jetzt versuchen

Also ich habe jetzt den neusten ESP 32 Arduino Core installiert und nutze davon auch die LittleFS
libary aber trotzdem kann ich kein Objekt von Dir erstellen

Warum kann ich kein Directory Object erstellen?