Go Down

Topic: Iterating through a Directory and storing the maximium file number as an integer (Read 616 times) previous topic - next topic

DennyP

Hello there,

I've got a default SD directory that contains .csv files entitled from 1 to 10.
I want to iterate through the directory and store the maximium number as an integer, in this case it would be 10.

I have a feel it would be

int maxFileNumber = max(for( i = 0; I < 9999; i++)......) where ..... is the part I don't know.

Cheers,
Dennis

robtillaart

a hint

char name[16];
m = 0;
for (int i=0; i< 9999; i++)
{
   sprintf(name, "%d.txt", i);
   if (open name is successful)
  {
      m = i;
      close name;
  }
}

at the end m contains the highest file number
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

DennyP

Thx Robtillaart!

This sprintf function is quite a useful thing !
I recognize what you mean by "if (open name is successful)" is:

"if (SD.exists(name))" where name is that character data type.

I was wondering what you meant by "close name", can you close the char datatype?
did you mean File.close()? (which we presumably not need cause we don't need to introduce the File class?)

Cheers,
DennyP

PaulS

Since Rob's suggestion was to open the file, you would need to close it.

Since SD.exists() doesn't actually open the file, there is no need to close it.

fat16lib

Here is a very fast function to find the "maximium file number as an integer"  It was developed for a user with a huge number of files so one pass through the directory was required.
Code: [Select]

#include <SD.h>
const uint8_t chipSelect = 10;
//------------------------------------------------------------------------------
// Return -2 if error, -1 not found, else max file number.
long maxFileNumber(const char* dirName, const char* baseName, const char* fileExt) {
  File dir;
  long maxNum = -1; 
  uint8_t len = strlen(baseName);

  dir = SD.open(dirName, FILE_READ);
  if (!dir || !dir.isDirectory()) return -2;
 
  while (true) {
    char *ext, *name, *ptr;
    dir_t d;
    // Return result if no more entries.
    if (dir.read(&d, 32) != 32 || d.name[0] == 0) return maxNum;
    // Only check existing regular files.
    if (d.name[0] == DIR_NAME_DELETED || !DIR_IS_FILE(&d)) continue;
    // Cast file extension to char* for ease of use
    ext = (char*)d.name + 8;
    ext[3] = 0;
    // Remove any blank fill.
    if ((ptr = strchr(ext, ' '))) *ptr = 0;
    // Skip if wrong file extension. Use case independent compare.
    if (strcasecmp(ext, fileExt)) continue;
    // Cast d.name to char* for ease of use
    name = (char*)d.name; 
    // Don't look at file extension
    name[8] = 0;     
    // Look for baseName with case independent compare.
    if (0 == strncasecmp(name, baseName, len)) {
      // Place for start of number.
      char* bgn = name + len;
      // Iterator
      char* ptr = bgn;
      long n = 0;
      // Get number.
      while (isdigit(*ptr)) n = 10*n + *ptr++ - '0';
      // make sure the end of the file name is a valid number.
      if (ptr != bgn && (*ptr == 0 || *ptr == ' ') && n > maxNum) maxNum = n;
    }
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  if (!SD.begin(chipSelect)) {
    Serial.println(F("SD.begin failed"));
    while(1);
  }
  Serial.print(F("ANALOG,BIN: "));
  Serial.println(maxFileNumber("/", "ANALOG", "BIN"));
  Serial.print(F("DATA,TXT: "));
  Serial.println(maxFileNumber("/", "DATA", "TXT"));
  Serial.print(F("SHORT,TX: "));
  Serial.println(maxFileNumber("/", "SHORT", "TX"));
  Serial.print(F("NOEXT,<null>: "));
  Serial.println(maxFileNumber("/", "NOEXT", ""));
  Serial.print(F("<nobase>,TXT: "));
  Serial.println(maxFileNumber("/", "", "TXT"));
  Serial.print(F("MISSING,TXT: "));
  Serial.println(maxFileNumber("/", "MISSING", "TXT"));
   Serial.print(F("<bad dir>: "));
  Serial.println(maxFileNumber("/BADDIR", "DATA", "TXT"));

  Serial.println(F("Done!"));
}
void loop() {}


I ran the program on an SD that had these files root directory:
Quote

12345678.TXT
ANALOG00.BIN
ANALOG01.BIN
ANALOG02.BIN
ANALOG03.BIN
ANALOG04.BIN
ANALOG05.BIN
ANALOG99.TXT
DATA000.TXT
DATA999.TXT
NOEXT00
NOEXT09
SHORT05.TX
TEST.CSV


Here is the test output:
Quote

ANALOG,BIN: 5
DATA,TXT: 999
SHORT,TX: 5
NOEXT,<null>: 9
<nobase>,TXT: 12345678
MISSING,TXT: -1
<bad dir>: -2
Done!


Note: Finding "12345678.TXT" by opening every possible file in the series would take close to forever.

Go Up