Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file.seek problem #7323

Closed
6 tasks done
lucasromeiro opened this issue May 23, 2020 · 10 comments · Fixed by #7324
Closed
6 tasks done

file.seek problem #7323

lucasromeiro opened this issue May 23, 2020 · 10 comments · Fixed by #7324

Comments

@lucasromeiro
Copy link

lucasromeiro commented May 23, 2020

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [2.7.1]
  • Development Env: [Arduino IDE]
  • Operating System: [MacOS]

Settings in IDE

  • Module: [Nodemcu]
  • Flash Size: [4MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200]

Problem Description

I have a project that uses the SPIFFS system, but now I have been informed that this system will be discontinued. So I switched to LittleFS.
However when doing this I have a problem with the SEEK function!
When using the function it is not working as expected!
I still don't understand what is happening, because it advances infinitely ...
Below I put 2 examples, one using SPIFFS and then LittleFS.
I don't know if this change affects other things.

  • I need to know how to fix this seek problem
  • I need to know if the switch to LittleFS affects other features or if it's just SEEK
//PROBLEM!!!

#include <LittleFS.h>
void setup() {
  LittleFS.begin();
  Serial.begin(19200);
  LittleFS.remove("/devices.cfg");
  File file;
  file = LittleFS.open("/devices.cfg", "a");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.close();
}
void loop() {
    File file;
    file = LittleFS.open("/devices.cfg", "r+");
    
    uint16_t quantLinhas = 0;
    uint32_t auxiliar = 0;
    
    while (file.seek((uint32_t)auxiliar, SeekSet))
    {
        yield();       
        ESP.wdtFeed(); 
        if (file.peek() == '\r')
        {
            quantLinhas++;
        }
        auxiliar++;
        Serial.println(auxiliar);
    }
    Serial.print("END:");
    Serial.println(quantLinhas);
    file.close();
    delay(1000);
  
  }

INCREMENT FOREVER...

Captura de Tela 2020-05-23 às 16 21 20

//GOOD!!!


#include <FS.h>//SPIFFS
void setup() {
  SPIFFS.begin();
  Serial.begin(19200);
  SPIFFS.remove("/devices.cfg");
  File file;
  file = SPIFFS.open("/devices.cfg", "a");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.println("Test");
  file.close();
}

// the loop function runs over and over again forever
void loop() {
    File file;
    file = SPIFFS.open("/devices.cfg", "r+");
    
    uint16_t quantLinhas = 0;
    uint32_t auxiliar = 0;
    
    while (file.seek((uint32_t)auxiliar, SeekSet))
    {
        yield();       
        ESP.wdtFeed(); 
        if (file.peek() == '\r')
        {
            quantLinhas++;
        }
        auxiliar++;
        Serial.println(auxiliar);
    }
    Serial.print("END:");
    Serial.println(quantLinhas);
    file.close();
    delay(1000);
  
  }

Captura de Tela 2020-05-23 às 16 22 28

@earlephilhower
Copy link
Collaborator

It is legal to seek past the end of a file: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html

You should be checking for error on the peek or read. Those should return failure when you're trying to read past the end of written data.

@lucasromeiro
Copy link
Author

It is legal to seek past the end of a file: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html

You should be checking for error on the peek or read. Those should return failure when you're trying to read past the end of written data.

I understand, I will look at your link and better check what happens, if I can handle the error that returns.
What I don't understand is why it changed from SPIFFS to LittleFS.
  I read that it was 100% compatible. But it seems that it is not.
Can you tell me if anything else has changed ??
I need to know this to correct it. Because we spent a lot of time finding these errors.

Thank you

@devyte
Copy link
Collaborator

devyte commented May 24, 2020

SPIFFS has limitations, that is one of several reasons it was deprecated. SPIFFS should NOT be considered a reference for compatibility. Instead, check that LittleFS is compliant with standard expected behavior for file handling, as linked above.

@lucasromeiro
Copy link
Author

lucasromeiro commented May 24, 2020

SPIFFS has limitations, that is one of several reasons it was deprecated. SPIFFS should NOT be considered a reference for compatibility. Instead, check that LittleFS is compliant with standard expected behavior for file handling, as linked above.

How can I do this verification on LittleFS?
Where do I find the documentation?
Can I find the changes that have taken place from SPIFFS to LittleFS somewhere? To avoid the same thing that occurred in seek.

@fabianoriccardi
Copy link

fabianoriccardi commented May 24, 2020

I think that the main documentation can be found here (LittleFS and SPIFFS).

However, it seems that the main reasons to switch FS are related to directory handling and filename length.

If you have any other source of information please post the link.

@lucasromeiro
Copy link
Author

It is legal to seek past the end of a file: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html

You should be checking for error on the peek or read. Those should return failure when you're trying to read past the end of written data.

I just checked and the SEEK function in SPIFFS returns 0 if it reaches the end of the file and 1 if it doesn't.
However, in LittleFS it always returns 1. When it reaches the end of the file or not, it always returns 1. I was unable to return something other than 1.
It looks like there really is a problem with the SEEK function on LittleFS !!!

@devyte
Copy link
Collaborator

devyte commented May 24, 2020

The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap.

Your expectation of fseek failing after end of file is not correct. As I said, SPIFFS is not the reference, it has issues and wrong behavior.

@lucasromeiro
Copy link
Author

The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap.

Your expectation of fseek failing after end of file is not correct. As I said, SPIFFS is not the reference, it has issues and wrong behavior.

I see, how can I solve this problem? Suggest me something?
In the documentation that @fabiuz7 posted above does not talk about how the SEEK function works and what the returns are.

earlephilhower added a commit to earlephilhower/Arduino that referenced this issue May 24, 2020
Fixes esp8266#7323

While I'm not a fan, the Arduino FileSeek API online shows that a seek()
past EOF should return FALSE.
https://www.arduino.cc/en/Reference/FileSeek

SPIFFS and SDFS obey this, but LittleFS followed the POSIX standard or
allowing seeks past EOF.

Update LittleFS::seek() to follow the Arduino API and add tests for it.
@earlephilhower
Copy link
Collaborator

After looking at this again I do have to grudgingly admit that fseek != Arduino's File::seek() in this respect. Their online docs, and the existing SDFS and SPIFFS, say that seeking past EOF is illegal and returns FALSE. So, IMO, this is a valid bug and a PR has been pushed to correct it.

@lucasromeiro
Copy link
Author

Great!
Thank you for looking more carefully.

earlephilhower added a commit that referenced this issue May 31, 2020
Fixes #7323

While I'm not a fan, the Arduino FileSeek API online shows that a seek()
past EOF should return FALSE.
https://www.arduino.cc/en/Reference/FileSeek

SPIFFS and SDFS obey this, but LittleFS followed the POSIX standard or
allowing seeks past EOF.

Update LittleFS::seek() to follow the Arduino API and add tests for it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants