espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.68k stars 7.42k forks source link

can not creat any file in subdirectory #6241

Open mkeyno opened 2 years ago

mkeyno commented 2 years ago

Board

SparkFun MicroMod ESP32 Processor (FireBeatle in Arduino IDE)

Device Description

SparkFun MicroMod ESP32 Processor

alongside of SparkFun MicroMod Qwiic Carrier Board - Single

Hardware Configuration

no hardware is attached

Version

v2.0.2

IDE Name

Arduino IDE

Operating System

windows 10

Flash frequency

80MHz

PSRAM enabled

yes

Upload speed

115200

Description

I've tried to run the SPIFF_test sample library (framework-arduinoespressif32\libraries\SPIFFS\examples\SPIFFS_Test\SPIFFS_Test.ino) however, I noticed I can not create any file in the subdirectory even with adding some changes following is my code

Sketch

#if ( ARDUINO_ESP32C3_DEV )
    // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS
    #define USE_LITTLEFS          false
    #define USE_SPIFFS            true
  #else
    #define USE_LITTLEFS    true
    #define USE_SPIFFS      false
#endif

#if USE_LITTLEFS
    // Use LittleFS
    #include "FS.h"

    // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
    //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) )  //(ESP_ARDUINO_VERSION_MAJOR >= 2)
    #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
      #warning Using ESP32 Core 1.0.6 or 2.0.0+
      // The library has been merged into esp32 core from release 1.0.6
      #include <LittleFS.h>

      FS* filesystem =      &LittleFS;
      #define FileFS        LittleFS
      #define FS_Name       "LittleFS"
    #else
      #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
      // The library has been merged into esp32 core from release 1.0.6
      #include <LITTLEFS.h>             // https://github.com/lorol/LITTLEFS

      FS* filesystem =      &LITTLEFS;
      #define FileFS        LITTLEFS
      #define FS_Name       "LittleFS"
    #endif

#elif USE_SPIFFS
    #include <SPIFFS.h>
    FS* filesystem =      &SPIFFS;
    #define FileFS        SPIFFS
    #define FS_Name       "SPIFFS"
#else
    // +Use FFat
    #include <FFat.h>
    FS* filesystem =      &FFat;
    #define FileFS        FFat
    #define FS_Name       "FFat"
#endif

/* You only need to format SPIFFS the first time you run a
   test or else use the SPIFFS plugin to create a partition
   https://github.com/me-no-dev/arduino-esp32fs-plugin */
#define FORMAT_SPIFFS_IF_FAILED true
    #include <SPIFFS.h>

    #define FileFS        SPIFFS
    #define FS_Name       "SPIFFS"

void listDir( const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\r\n", dirname);

    File root = FileFS.open(dirname);
    if(!root){
        Serial.println("- failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println(" - not a directory");
        return;
    }
   else {Serial.print("level");Serial.println(levels);}
    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("\tSIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void readFile( const char * path){
    Serial.printf("Reading file: %s\r\n", path);

    File file = FileFS.open(path);
    if(!file || file.isDirectory()){
        Serial.println("- failed to open file for reading");
        return;
    }

    Serial.println("- read from file:");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

void writeFile( const char * path, const char * message){
    Serial.printf("Writing file: %s\r\n", path);

    File file = FileFS.open(path, FILE_WRITE);
    if(!file){
        Serial.println("- failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("- file written");
    } else {
        Serial.println("- write failed");
    }
    file.close();
}

void appendFile( const char * path, const char * message){
    Serial.printf("Appending to file: %s\r\n", path);

    File file = FileFS.open(path, FILE_APPEND);
    if(!file){
        Serial.println("- failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("- message appended");
    } else {
        Serial.println("- append failed");
    }
    file.close();
}

void renameFile( const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\r\n", path1, path2);
    if (FileFS.rename(path1, path2)) {
        Serial.println("- file renamed");
    } else {
        Serial.println("- rename failed");
    }
}

void deleteFile(const char * path){
    Serial.printf("Deleting file: %s\r\n", path);
    if(FileFS.remove(path)){
        Serial.println("- file deleted");
    } else {
        Serial.println("- delete failed");
    }
}

void testFileIO( const char * path){
    Serial.printf("Testing file I/O with %s\r\n", path);

    static uint8_t buf[512];
    size_t len = 0;
    File file = FileFS.open(path, FILE_WRITE);
    if(!file){
        Serial.println("- failed to open file for writing");
        return;
    }

    size_t i;
    Serial.print("- writing" );
    uint32_t start = millis();
    for(i=0; i<2048; i++){
        if ((i & 0x001F) == 0x001F){
          Serial.print(".");
        }
        file.write(buf, 512);
    }
    Serial.println("");
    uint32_t end = millis() - start;
    Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end);
    file.close();

    file = FileFS.open(path);
    start = millis();
    end = start;
    i = 0;
    if(file && !file.isDirectory()){
        len = file.size();
        size_t flen = len;
        start = millis();
        Serial.print("- reading" );
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            if ((i++ & 0x001F) == 0x001F){
              Serial.print(".");
            }
            len -= toRead;
        }
        Serial.println("");
        end = millis() - start;
        Serial.printf("- %u bytes read in %u ms\r\n", flen, end);
        file.close();
    } else {
        Serial.println("- failed to open file for reading");
    }
}

void setup(){
    Serial.begin(115200);
    while(!Serial);
    Serial.print("FS selected=");Serial.println(FS_Name);
    if(!FileFS.begin(FORMAT_SPIFFS_IF_FAILED)){
        Serial.println("SPIFFS Mount Failed");
        return;
    }

    listDir( "/", 3);
    writeFile( "/hello.txt", "Hello ");
    writeFile( "/a/a2.txt", "Hello ");
    writeFile( "/a/b.txt", "Hello ");
    writeFile( "/a/b/c3.txt", "Hello ");
   // appendFile( "/hello.txt", "World!\r\n");
   // readFile( "/hello.txt");
   // renameFile( "/hello.txt", "/foo.txt");
   // readFile( "/foo.txt");
   // deleteFile(SPIFFS, "/foo.txt");
  //  testFileIO(SPIFFS, "/test.txt");
  //  deleteFile(SPIFFS, "/test.txt");
  //  Serial.println( "Test complete" );
    listDir( "/", 3);
}

void loop(){

}

Debug Message

Listing directory: /
level3
  FILE: foo.txt SIZE: 14
  FILE: hello.txt   SIZE: 6
  FILE: bhello.txt  SIZE: 6
  FILE: hello.txt   SIZE: 6
  FILE: hello.txt   SIZE: 14
Writing file: /hello.txt
- file written
Writing file: /a/a2.txt
- file written
Writing file: /a/b.txt
- file written
Writing file: /a/b/c3.txt
- file written
Listing directory: /
level3
  FILE: foo.txt SIZE: 14
  FILE: hello.txt   SIZE: 6
  FILE: bhello.txt  SIZE: 6
  FILE: hello.txt   SIZE: 6
  FILE: hello.txt   SIZE: 6
  FILE: a2.txt  SIZE: 6
  FILE: b.txt   SIZE: 6
  FILE: c3.txt  SIZE: 6

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

VojtechBartoska commented 2 years ago

Hello, sorry for answering late. Is this still valid?

mkeyno commented 2 years ago

@VojtechBartoska yes it is

VojtechBartoska commented 2 years ago

Ok, linking this to grouped issue where we will investigate this more.

igrr commented 2 years ago

I think the issue here is that file.name() returns the last component of the filename (compared to file.path() which returns the complete path). At the same time, SPIFFS doesn't have a concept of directories, it's just that file names may contain forward slashes. SPIFFS class tries to pretend that directories actually exist (hence file.name() returns something different from file.path()) but doesn't quite get there.

At minimum we should document this behavior, issue tracking documentation updates is referenced above.

mkeyno commented 2 years ago

@igrr with ESP8266 object Dir works fine, but this object has depricated in new FS lib

gasagna commented 2 years ago

@igrr Do you know of any workaround?

lbernstone commented 2 years ago

The best workaround is to use LittleFS. This is just one of the undesirable behaviors of SPIFFS.