Read filename from SD card, store to a string

Hello,

Been scratching my head for a little while, I cant seem to figure out how to read a file name of a file I have on SD card, and save the file name (not its contents, just the file name itself) to a string.
What I am trying to do is build an array of file names. I am using the SDFAT library.

Better yet, the files are actually numbers, ranging from 0001.mp3 to 9999.mp3

Can someone point me in the right direction for reading the file name, say 0001.mp3, and saving this an int variable. So it will be 1 to 9999.

Thanks in advance.

I found this:

//------------------------------------------------------------------------------
/** Get a file's name
 *
 * \param[out] name An array of 13 characters for the file's name.
 *
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
bool SdBaseFile::getFilename(char* name) {
  dir_t* p;
  if (!isOpen()) {
    DBG_FAIL_MACRO;
    goto fail;
  }
  if (isRoot()) {
    name[0] = '/';
    name[1] = '\0';
    return true;
  }
  // cache entry
  p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
  if (!p) {
    DBG_FAIL_MACRO;
    goto fail;
  }
  // format name
  dirName(*p, name);
  return true;

 fail:
  return false;
}

However this is big boys code, and I cant understand what it means exactly, where the name of the file actually goes...

  • \param[out] name An array of 13 characters for the file's name.

what is this param[out] exactly?

or is that wrong...

Is it if I start at the begining of the directory, and call that function, it will tell me yes/no if the file exists...

ie
boolean SongPresent = getFilename("0001.mp3");

?

I could possibly make that work, but ideally I want to start at the beginning of the root directory, and scan through all the files on the card, returning the name of the file, ideally just the name, saving it into an int array.

hmm. The search continues.

EDIT Actually, this would be better for that example

//------------------------------------------------------------------------------
/** Test for the existence of a file in a directory
*

  • \param[in] name Name of the file to be tested for.
  • The calling instance must be an open directory file.
  • dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory
  • dirFile.
  • \return true if the file exists else false.
    /
    bool SdBaseFile::exists(const char
    name) {
    SdBaseFile file;
    return file.open(this, name, O_READ);

Not really sure what the one above is for.

Currently I do this

// open next file in root.  The volume working directory, vwd, is root
  while (sdCardFile.openNext(sdCard.vwd(), O_READ)) 
{
  MaxFiles++;
    
  sdCardFile.close();
}

which is mostly extracted from one of the examples.
So it just increments through all the files in root, and adds 1 to the count. I then get the total file count out at the end.

Its this I want to extend on, so not only get the file count, but get a list of ints, of all the files present in root.

Cheers

Essentially I want this:

//------------------------------------------------------------------------------
/** Print a file's name
 *
 * \param[in] pr Print stream for output.
 *
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
bool SdBaseFile::printName(Print* pr) {
  char name[13];
  if (!getFilename(name)) {
    DBG_FAIL_MACRO;
    goto fail;
  }
  return pr->print(name) > 0;

 fail:
  return false;
}

But I dont want to print it to the serial port...

:~

Really showing the gaps in my knowledge here.

I cant seem to figure out how to read a file name of a file I have on SD card, and save the file name (not its contents, just the file name itself) to a string.

Nor, it seems, can you figure out how to post your code.

Can someone point me in the right direction for reading the file name, say 0001.mp3, and saving this an int variable. So it will be 1 to 9999.

int num = 0;
while(file.available() > 0)
{
   char ltr = file.read();
   if(ltr >= '0' && ltr <= '9')
   {
      num *= 10;
      num += ltr - '0';
   }
   else // found the ., the m, the p, the 3, the <cr>, or the <lf>
   {
      // Save num somewhere

      num = 0;
   }
}

Nor, it seems, can you figure out how to post your code.

Um... my code has absolutely nothing to do with this Paul.
If I wanted to post my code I would have done so, but it has absolutely no relevance to this question.

Thanks for the snippet you posted, ill digest it and see if its what I need.

Regards

Um... my code has absolutely nothing to do with this Paul.

If your code has nothing to do with reading file names from the SD card, why are you trying to do it?

Why do you want to see my MP3 player code, when its not related to the question I am asking.
I could have a new project with no code, and I want to read the file name using the SDFAT library, and there would be no code to post.

The only thing relating to opening a file is the part I posted above, which is directly out of the example from the SDFAT library, I have gotten no where further than that.

Why do you want to see my MP3 player code, when its not related to the question I am asking.

Because I assumed that you had tried something, and failed, or hit a wall, or something. So I was wrong. Sue me.

:~

Not enough sleep at my end I think.

Everything I have tried I have posted. All I am trying to do is find the function or the method to read the file name using the sdfat library.

I have just searched the sdfat library and cant find a function called available()

while(file.available() > 0)

Where is this from?

WanaGo:
I could have a new project with no code, and I want to read the file name using the SDFAT library, and there would be no code to post.

If that was the case, you would have been wasting everyone's time by asking for help before you had made any attempt to solve the problem for yourself.

If this problem is a small part of a complex sketch then write a new sketch which demonstrates the problem in the simplest possible way. You will find this often helps you to make progress on the problem yourself since it forces you to test assumptions about which parts of your code are relevant to the problem.

In this case you want to open the directory (using SD.open()), access each file in turn (using File.openNextFile()) and get the file name (using File.name()).

If you know the file name includes a decimal number and want to know what the number is, you need to parse the number from the string. The C runtime library provides various functions such as atoi() to do that sort of thing.

This does not look terribly difficult and I would have thought you could at least have a stab at it before you give up and ask for help. Showing us your attempt would also show us which parts of this problem you have solved and which parts are causing you trouble, so the people trying to help you aren't left trying to solve the whole problem for you from scratch, which seems to be the situation at the moment.

I have this, which I posted above

// open next file in root.  The volume working directory, vwd, is root
  while (sdCardFile.openNext(sdCard.vwd(), O_READ)) 
{
  MaxFiles++;
    
  sdCardFile.close();
}

And I essentially want to do something like this:

// open next file in root.  The volume working directory, vwd, is root
  while (sdCardFile.openNext(sdCard.vwd(), O_READ)) 
{
  MaxFiles++;
  sdCardFile.printName(??) //But I dont want to print to a serial stream, I want to print to a int, or a string
    
  sdCardFile.close();
}

Cheers

I appreaciate that, but I have posted what I tried.

I didnt just go and write code I know wouldnt work, I tried looking at the sdfat library first to find a function which was suitable, but I havent found one that I understand how to use, hence the post...

There is no more code to post as I havent written any....

Im confused why this is so much of an issue... should I be trying stuff I have no idea if it will work, or should I be reading the library to find something suitable first. I thought the 2nd option was the valid option here...

Sorry if I have offended anyone, but I just havent written non working code, would like to find a viable solution from the library first...

In this case you want to open the directory (using SD.open()), access each file in turn (using File.openNextFile()) and get the file name (using File.name()).

This is what I am essentially doing, but I cant find the name() you are speaking of...

Crap ok, found it.

I was using these:

//Add the SdFat Libraries
#include <SdFat.h>
#include <SdFatUtil.h>

not the base SD library.

I see available() now too.

Thanks

Where is this from?

Left field. I thought you were trying to read the name FROM a file, not the name OF a file.

WanaGo:
Crap ok, found it.

I was using these:

//Add the SdFat Libraries
#include <SdFat.h>
#include <SdFatUtil.h>

not the base SD library.

I see available() now too.

Thanks

If you'd posted your actual code (in its entirety), we'd have known that.

I did say in post #1 I am using the SDFAT library, not the SD library. Also posted pieces of the SDFAT functions. I didnt even know there was a SD library 'wrapper' or whatever its called to be honest.

Tried implmenting the SD library instead, but its not compiling. Looks like the 2012 SDFAT library I am using is not quite the same as the 2009 SDFAT library which is part of the SD library included with Arduino 1.01

No luck so far, will keep trying.

It's easy to find excuses not to, or reasons why we should have guessed or noticed some quirk of your solution, but there's simply no substitute for posting your actual code when you need help with a coding problem.

I'm a real noob, so don't jump on me as I haven't written any code.
I'm looking for a sample of code to do exactly what the OP was trying to do but I stumble into too many issues over creating a dynamic string array and reading each file name. There are too many libraries and I'm not a programmer. I'd appreciate some help.
I need a simple sketch that creates a character array, opens the root directory, reads the names and appends them to the array to allow it to be read and accessed later. This will be used to play .wav files from the card. I have code to read a named .wav file and play it from the SD card but this string manipulation part of the project eludes me.
I have looked at the CardInfo example but can't understand how to move the read list to a script. I've tried to modify the openNextFile example on the arduino reference site, but can't go from printing the file names to adding them to a script. I'm sure that this is simple but it's beyond me.
I know I'm asking for someone to post a short sketch for me, I do hope people don't find this offensive, but I am lost.

Thanks in advance

Shane