Hi, I can see in the library how to traverse the directory from start to finish, but the only way I can see to do a reverse traverse from the end is to read the file names into an array, and then write out the array, starting from the end. This seems like an arduino-memory-unfriendly approach. i really would like a way to print a directory newest first!
A directory does not necessarily contain files in the same order they were created, especially if you ever delete a file.
Imagine this scenario: create file A, create file B, delete file A, create file C. File C might be the first one in the directory because it could take the directory slot that was previously taken by A.
If you look at the SD Card directory browse on my Arduino system at http://www.2wg.co.nz you will notice that sub-directories and files are listed in alphabetical order with sub-directories first and then the filenames.
If you browse to http://www.2wg.co.nz/HACKLOGS/ you will notice files listed in chronological order - but that is only because the filenames in alphabetical order also happen to be in chronological order.
Reading your query I think you want files in reverse datetime order. I cannot help you with that because my application does not process (set or retrieve) file dates and times.
However within the source code or my Arduino web server application and within the SD Card directory browsing procedures you will find the code that generates the sorted sub-directory and filename listings. It uses a combination of a small five element sort array (String l_SortList[C_SortMax]; ) and multiple iterations of an SD Card directory to extract sub-directory names and filenames for sorting. This technique might be of interest to you.
The source code for my application can be found on the website within the SD Card PUBLIC sub-directory and can be downloaded. The current main sketch file is HA150314.INO
Look for the procedure name SDCardDirectoryBrowse().
I eventually found that there would never be more than 512 files in the root directory [Maximum number of files on SD card. - Storage - Arduino Forum thanks!], so I wastefully used due memory to build a 512 array of file dir_t entries, and then worked this back. Did what I wanted with Sd.h. I think much better solutions would be possible with SDfat.h
void printDirectory(uint8_t flags) {
// This code is just copied from SdFile.cpp in the SDFat library
// and tweaked to print to the client output in html!
dir_t pAll[512];
dir_t p ;
int iFiles = 0 ;
root.rewind();
while (root.readDir(p) > 0)
{
// done if past last used entry
if (p.name[0] == DIR_NAME_FREE) break;
// skip deleted entry and entries for . and ..
if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;
// only list subdirectories and files
if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
memcpy (&pAll[iFiles], &p, sizeof(dir_t));
iFiles ++ ;
}
//iFiles -- ; // allow for last increment...
client.print (iFiles);
client.println F(" files found on disk ");
client.println F("<ul>");
for (int i = iFiles; i--; i >= 0)
{
// now print them out in reverse order
memcpy (&p, &pAll[i], sizeof(p));
// print any indent spaces
client.print F("<li><a href=\"");
for (uint8_t i = 0; i < 11; i++)
{
if (p.name[i] == ' ') continue;
if (i == 8) {
client.print('.');
}
client.print(char(p.name[i]));
}
client.print F("\">");
// print file name with possible blank fill
for (uint8_t i = 0; i < 11; i++)
{
if (p.name[i] == ' ') continue;
if (i == 8) {
client.print('.');
}
client.print(char(p.name[i]));
}
client.print F("</a> ");
/////////////////////////////// now put in a link for a picture
if (char(p.name[10]) == 'G')
{ // print any indent spaces
client.print F(" <a href=\"");
for (uint8_t i = 0; i < 10; i++)
{
if (p.name[i] == ' ') continue;
if (i == 8) {
client.print('.');
}
client.print(char(p.name[i]));
}
client.print F("P\"> (picture)</a>");
///////////////////////////////
}
if (DIR_IS_SUBDIR(&p))
{
client.print('/');
}
else
// print size
{
myPrintFatDateTime(p);
client.print F(" size: ");
client.print(p.fileSize);
}
client.println F("</li>");
}
client.println F("</ul>");
}
If you would traverse the folder twice you could count the entries in the first run so you do not need to allocate more space than needed.
Another option is to create a sort of skip list,
Allocate 26 + 20 entries, go through the list and record every 20th entry.
suppose you have 149 entries.
then 7 entries will be used (of the 26)
go to the last one, read the last 9 entries (into the 20) and print them in reverse
go to the 6th, read 20 entries , print them in reverse
go to the 5th, read ....
go to the first, read the "first 20" entries, print them in reverse
then you only need 46 dir-entries iso 512, substantial reduce of memory