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

open by index and LFN #27

Closed
mr-stivo opened this issue Oct 17, 2019 · 5 comments
Closed

open by index and LFN #27

mr-stivo opened this issue Oct 17, 2019 · 5 comments

Comments

@mr-stivo
Copy link

Hi,

I'm currently working on converting a project from SdFat to SdFat-beta so I can ultimately make the change from a teensy 3.6 to a teensy 4. My project uses open by index to navigate through large directories containing many files. Since switching to SdFat-beta I can no longer get an LFN using getName() when the file is opened by index.

Hardware: teensy 3.6
Arduino 1.8.10
Teensyduino 1.48

Using OpenNext as an example I made some changes for troubleshooting. First, I modified the code to use getName().

//file.printName(&Serial);  // COMMENT OUT
char str[255];              // ADD
file.getName(str, 255);     // ADD
Serial.print(str);          // ADD

Running the code like this produces the expected output:

Type any character to start
     0 2019-10-17 18:41 With.Two dots.txt
     0 2019-10-17 18:41 A long name can be 255 characters.txt
     0 2019-10-17 18:42 lower.txt
     0 2019-10-17 18:42 MIXCASE.txt
     0 2019-10-17 18:42 mixed.TXT
     0 2019-10-17 18:42 Not_8_3.txt
     0 2019-10-17 18:42 OK%83.TXT
     0 2019-10-17 18:43 STD_8_3.TXT
     0 2019-10-17 18:43 With Blank.txt
     0 2019-10-17 18:43 sub folder/
Done!

Now I modify the code to use open by index instead of openNext:

//while (file.openNext(&dir, O_RDONLY)) {    // COMMENT OUT
for(int i=0; i<25; i++) {                    // ADD - the 25 is a meaningless number for troubleshooting
  file.open(&dir, i, O_RDONLY);              // ADD

With this change getName never returns a LFN.

Type any character to start
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 WITHTW~1.TXT
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 
     0 2019-10-17 18:41 ALONGN~1.TXT
     0 2019-10-17 18:42 lower.txt
     0 2019-10-17 18:42 MIXCASE.txt
     0 2019-10-17 18:42 mixed.TXT
     0 2019-10-17 18:42 
     0 2019-10-17 18:42 NOT_8_3.TXT
     0 2019-10-17 18:42 OK%83.TXT
     0 2019-10-17 18:43 STD_8_3.TXT
     0 2019-10-17 18:43 
     0 2019-10-17 18:43 
     0 2019-10-17 18:43 WITHBL~1.TXT
     0 2019-10-17 18:43 
     0 2019-10-17 18:43 SUBFOL~1/
     0 2019-10-17 18:43 
     0 2019-10-17 18:43 
Done!

Any ideas?

On a side note, there may be some strange behavior with isHidden() as well but I have not looked that far into it.

Thanks in advance for your help and thank you so much for the quick teensy 4 support.

@greiman
Copy link
Owner

greiman commented Oct 17, 2019

There is more than one directory entry for each file with a long file name. The only reliable way to get the correct index is to open the file by path and save the index.

The short file name entry is used to open the file. It is the last entry in the group. You must have the index of the first entry in the group to get the file name.

There can be isolated empty directory entries that can't be used for any lFN file.

So don't expect open by index to work if you an index other than to one returned by open by path.

@greiman
Copy link
Owner

greiman commented Oct 17, 2019

Open by index on SdFat-beta opens the SFN directory entry and does not determine the LFN offset.

I will modify open by index to set the LFN offset.

@mr-stivo
Copy link
Author

I was just finishing this up when I saw you posted another reply. I still wanted to show you how I was using open by index.

Here is a better example of how I'm using open by index. The reason I use it this way is I'm displaying a scrollable directory listing and sometimes the directories have 100s of files. Since the memory is limited, keeping the index for the "top" of the list is much easier and I don't have the performance hit of parsing the entire directory multiple times.

You can change the library and the USE_SD_BETA define. teensy 3.6.

Code:

#include "SdFat.h"

#define USE_SD_BETA 0

#if USE_SD_BETA
#define SD_CONFIG SdSpiConfig(SDCARD_SS_PIN, DEDICATED_SPI)
SdFat sd;
#else
SdFatSdio sd;
#endif

File dir;
File file;

char n[512];

void setup() {
    Serial.begin(9600);
  
    while (!Serial) SysCall::yield();
  
    Serial.println("Type any character to start");
    while (!Serial.available()) SysCall::yield();

#if USE_SD_BETA
    if (!sd.begin(SD_CONFIG)) sd.initErrorHalt(&Serial);
#else
    if (!sd.begin()) sd.initErrorHalt(&Serial);
#endif
    
    if (!dir.open("/testdir")) Serial.println("dir.open failed");

    Serial.println("\n-- openNext --");
    while (file.openNext(&dir, O_RDONLY) ) {
        if(file.isHidden()==false) {
            file.getName(n, 512);
            Serial.printf("[%s]\n", n);
        }
        file.close();
    }

    Serial.println("\n-- open by index --");
    for(int i=0; i<25; i++) {
        if(file.open(&dir, i, O_RDONLY) && file.isHidden()==false) {
            file.getName(n, 512);
            Serial.printf("[%s]\n", n);
        }
        file.close();
    }
}

void loop() {
}

Using SdFat:

-- openNext --
[With.Two dots.txt]
[A long name can be 255 characters.txt]
[lower.txt]
[MIXCASE.txt]
[mixed.TXT]
[Not_8_3.txt]
[OK%83.TXT]
[STD_8_3.TXT]
[With Blank.txt]
[sub folder]

-- open by index --
[With.Two dots.txt]
[A long name can be 255 characters.txt]
[lower.txt]
[MIXCASE.txt]
[mixed.TXT]
[Not_8_3.txt]
[OK%83.TXT]
[STD_8_3.TXT]
[With Blank.txt]
[sub folder]

Using SdFat-beta:

-- openNext --
[With.Two dots.txt]
[A long name can be 255 characters.txt]
[lower.txt]
[MIXCASE.txt]
[mixed.TXT]
[Not_8_3.txt]
[OK%83.TXT]
[STD_8_3.TXT]
[With Blank.txt]
[sub folder]

-- open by index --
[WITHTW~1.TXT]
[ALONGN~1.TXT]
[lower.txt]
[MIXCASE.txt]
[mixed.TXT]
[NOT_8_3.TXT]
[OK%83.TXT]
[STD_8_3.TXT]
[WITHBL~1.TXT]
[SUBFOL~1]

@greiman
Copy link
Owner

greiman commented Oct 17, 2019

Try the latest version. getName should work for LFN files opened by index.

@mr-stivo
Copy link
Author

The latest version is working well:

-- open by index --
[With.Two dots.txt]
[A long name can be 255 characters.txt]
[lower.txt]
[MIXCASE.txt]
[mixed.TXT]
[Not_8_3.txt]
[OK%83.TXT]
[STD_8_3.TXT]
[With Blank.txt]
[sub folder]

Thanks so much for the quick fix!

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

No branches or pull requests

2 participants