greiman / SdFat

Arduino FAT16/FAT32 exFAT Library
MIT License
1.05k stars 497 forks source link

Migration to 2.* .. how to use chdir() when there's no vwd() or cwd() #353

Open nealcrook opened 2 years ago

nealcrook commented 2 years ago

(This is a similar question to #288

Hi Bill,

thanks for creating, documenting and sharing SdFat. I have a question about migration from 1. to 2.. Previously I did this:

SdFat SD;
.
.
.
SD.begin(...);
if (condition) {
   SD.chdir("MYDIR");
}
else {
  SD.chdir("MYOTHERDIR");
}

and all through my code I did stuff like:

handle.open("MYFILE");

in the knowledge that MYFILE would be created in The Right Place

At one point, I want to list the contents of the directory in use (MYDIR or MYOTHERDIR) and for various reasons don't want to use the in-built format but to format the output myself, so I did this:

working_dir = SD.vwd();
working_dir->rewind();
while (handle.openNext(working_dir, O_RDONLY)) {
 ...
}

With release 2. the absence of vwd()/cwd() means that I cannot use openNext in this way. It looks like, to use it, I need to not* use chdir, but to track the cwd myself and use it for every file operation:

SD.begin(...);
if (condition) {
   working_dir.open("MYDIR");
}
else {
  working_dir.open("MYOTHERDIR");
}

and all through my code do stuff like:

handle.open(&working_dir, "MYFILE");

Just so that, eventually, I can do this:

working_dir.rewind();
while (handle.openNext(&working_dir, O_RDONLY)) {
 ...
}

Your example DirectoryFunctions/DirectoryFunctions.ino seems to acknowledge this by the way it only uses openNext after explicitly opening a directory, where earlier in the code it was using chdir().

So, in summary, my questions are:

thanks and regards,

Neal

greiman commented 2 years ago

I made vwd private since internal use conflicts with use in some application.

There no longer is a single cwd since it can't exist for all combinations of FAT/exFat volumes since they are different class types.

I have implemented a simple solution in SdFat-beta that will soon be in the release version.

A cwd exists for each volume type. here is an example for SdFat/File.

// example without error checks and uses simple default arguments.
#include "SdFat.h"
// sd, cwd and file must be compatible types. 
SdFat sd;
File cwd;
File file;

void setup() {
  Serial.begin(9600);
  sd.begin();
  sd.chdir("MyDir");
  cwd.openCwd();
  while(file.openNext(&cwd)) {
    file.printName(&Serial);
    Serial.println();
    file.close();
  }
  Serial.println("Done");
}
void loop() {}

Here is the output:

file1.txt
file2.txt
Done
nealcrook commented 2 years ago

Hi Bill, thank you for your suggestion; it looks like a good, clean solution to my problem. I have downloaded SdFat-beta. I will test it with my application and report back. regards, Neal.

maxbrito500 commented 1 year ago

Thanks, it would help to include this tidybit of information on the examples.

Here is an implementation for the ls command that required the cwd functionality:

// prints a line of text
void func_ls(char *args, Stream *response ){
  File dir;
  File file;

  // open the current directory
  if (!dir.openCwd()){
    response -> println("Failed to open the directory");
    return;
  }

  while (file.openNext(&dir, O_RDONLY)) {
    //String fileName = file.name();

    char fileName[13];
    size_t len = file.getName(fileName, sizeof(fileName));

    if(file.isDirectory()){
      response -> print(fileName);
      response -> println("/");
    }else{
      response -> println(fileName);
    }
    file.close();
  }
}