Pages: [1]   Go Down
Author Topic: Iterating through a Directory and storing the maximium file number as an integer  (Read 516 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13707
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Tillaart

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

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Edison Member
*
Karma: 64
Posts: 1635
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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.
Logged

Pages: [1]   Go Up
Jump to: