DirectoryIterator


#1

Sorry if this sounds a noob question but there’s a way , or another class like “DirectoryIterator” to list directories aswell as files?.

In example:

// create directory iterator
DirectoryIterator dir_iterator(File("C:\\"),false);

// iterate until all
while(dir_iterator.next())
{
	// get file
	File file_found(dir_iterator.getFile());

// continue doing stuff...

}

But I only get files listed, any way to get folders listed too?

Thank you for your attention.


#2

take a look at File::findChildFiles()


#3

Files are directories, just iterate through things as I want. I have a program that dumps an entire directory tree, files, directories, and all into an html file (xml/html) using the function he stated. :slight_smile:


#4

Indeed, File::findChildFiles() worked well, thx.


#5

OvermindDL1

would you mind letting me have the source for the program that dumps the entire file tructure is folders and files into a html/xml doc?


#6

Er… will have to hunt it down, I ended up rewriting it in Python since I kept changing things specific to the situation I was using it in. It was very simple though…


#7

Well, i’ll be honest I was about to embark on writing something like that and would rather not re-invent the wheel.

If you could find it that would be great or else I will just write one myself.

Thanks


#8

Probably on an old drive, not in one of my current listings. I have well over 1500 projects spread across 6 drives, so searching takes some time with what little time I have. Might just be better for me to rewrite it, it was very simple as stated…


#9

I am trying to create an XML file of a directory structure. I want the XML file to be in the following format:



file1.txt
comments




file1.txt
comments


I get the first folder node then it adds all files including sub directory files as childeren to the first folder node. here is my code could some tell me where I am going wrong. I bet it is something stupid.

[code] //[UserButtonCode_textButton] – add your button handler code here…
String filename;
String outline, currentdoc, currentpath, lastpath;
String message;
float progress;
filename = mStartDir->getText();
filename << “\” ;
filename << mFileOut->getText() ;
File logfile ( “D:\development\BIndex\bindex.log” );
logfile.replaceWithText( “Start of Logfile …” + Time::getCurrentTime().toString (true, true) );
XmlElement dirtree (“DirectoryTree”);
lastpath = mStartDir->getText();
lastpath << “\”;
logfile.appendText("\nlastpah = " + lastpath );
XmlElement* mXmlFolder = new XmlElement (“Folder”);
mXmlFolder->setAttribute( T(“Name”), lastpath );
// dirtree.addChildElement( mXmlFolder );
StringArray dirlist;
DirectoryIterator iter (File (mStartDir->getText()), true, “.”);

	while (iter.next())
	{
		File theFileItFound (iter.getFile());
		currentdoc = theFileItFound.getFileName();
		currentpath = theFileItFound.getFullPathName();
		currentpath = currentpath.upToFirstOccurrenceOf( currentdoc, false, true );
		logfile.appendText("\nCurrentpath = " + currentpath + "\nLastpath = " + lastpath );
		progress = iter.getEstimatedProgress();
		message = "";
		message << int ( progress * 100 );
		message << " % complete";
		textEditor->setText( message );
		if ( currentpath != lastpath )
		{
			logfile.appendText( "\nInside currentpath != lastpath" );
			dirtree.addChildElement( mXmlFolder );
			logfile.appendText( "\nadded to dirtree" );
			XmlElement* mXmlFolder = new XmlElement ("Folder");
			logfile.appendText( "\ncreated new cmlelement for folder" );
			mXmlFolder->setAttribute( T("Name"), currentpath );
			logfile.appendText( "\nadded textelement to folder" );
			lastpath = currentpath;
			logfile.appendText( "\n set lastpath = currentpath" );
		}
		else
		{
			XmlElement* mXmlFile = new XmlElement ( "File" );
			XmlElement* mXmlName = new XmlElement ( "Name" );
			XmlElement* mXmlComment = new XmlElement ( "Comments" );
			mXmlName->addTextElement( currentdoc );
			mXmlComment->addTextElement( "Enter comments" );
			mXmlFile->addChildElement( mXmlName );
			mXmlFile->addChildElement( mXmlComment );
			logfile.appendText( "\nxmlfolder name = " + mXmlFolder->getStringAttribute( T("Name") ) );
			mXmlFolder->addChildElement( mXmlFile );
		}
	}
	logfile.~File();

// dirtree.addChildElement( mXmlFolder );
String myXmlDoc = dirtree.createDocument (String::empty);
File xmldocfile ( filename );
xmldocfile.replaceWithText( myXmlDoc );

	//[/UserButtonCode_textButton]
}
else if (buttonThatWasClicked == textButton2)
{
    //[UserButtonCode_textButton2] -- add your button handler code here..
	JUCEApplication::getInstance()->systemRequestedQuit();
    //[/UserButtonCode_textButton2]
}
else if (buttonThatWasClicked == textButton3)
{
    //[UserButtonCode_textButton3] -- add your button handler code here..
	FileChooser myChooser ("Please select the directory you want to index...",
		File::getSpecialLocation( File::userHomeDirectory )
                           );

    if (myChooser.browseForDirectory())
    {
        File IndexDir (myChooser.getResult());
		mStartDir->setText (   IndexDir.getFullPathName() );
    }
    //[/UserButtonCode_textButton3][/code]

#10

Why you don’t use recursions for the purposes like this?


#11

What are recursions?
How would I do that?

I am a hobby programmer so I am not that good.


#12

Yes, mine used recursion, which is just where the function calls itself.

Mine was setup so that it first did the setup, as usual, then checked for subdirectories, if found, it then iterates them calling itself with each subdirectory (as a juce::file) where the process would be repeated until it hits a directory with no subdirectories, it then saved out files if any and returned.


#13

Recursion is when a function calls itself (as OvermindDL1 has mentioned).

Your code is supposed to look like this:

XmlElement* SearchNode(XmlElement *pCurrentRoot, String sFolder)
{
       DirectoryIterator iter (sFolder, true, "*.*");

       XmlElement *l_pNode = 0;
       while(iter.next())
       {
          String l_sPath(iter.getFile().getFullPathName());
          if(iter.getFile().isDirectory())
          {
             l_pNode = new XmlElement("Folder");
             l_pNode->setAttribute( T("Name"), l_sPath);

             l_pNewNode = SearchNode(l_pNode, l_sPath);//!!!!!!!THIS IS THE RECURSION!!!!!!!

             if(l_pNewNode)
               pCurrentRoot->addChildElement(l_pNewNode);
          }
          else
          {
             l_pNode = new XmlElement("File");
             l_pNode->setAttribute( T("Name"), l_sPath);
             pCurrentRoot->addChildElement(l_pNode);
          }
       }

       return l_pNode;

}

The code is rough (out of my head), so think yourself since now you know what recursion is. You may google the recursion and read! :slight_smile:


#14

Ptomaine thanks for that, I am now just having trouble trying to write that to a file.
I have set the SearchNode up as a seperate function. But when I try to call it I get an error during compile:
error C3861: ‘SearchNode’: identifier not found

I am trying to use the XmlElement.createDocument on the SeachNode XmlElement return from calling it. am I wrong to try and use that?


#15

I am most likely getting the C3861 because SearchNode has not be declared correctly as a function.

So I guess my question is should I implement SearchNode as a function or a a member function in a class?


#16

I got it to work, I did not have the prototype definition for the function.
The resulting xml file looks like:

<Folder Name="C:\MyDocs\Clients\aa\"> <File Name="C:\MyDocs\Clients\aa\C17232.doc"/> <File Name="C:\MyDocs\Clients\aa\Changes Log.xls"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 3.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 4.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 5.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 6.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 7.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Scope Change.doc"/> <File Name="C:\MyDocs\Clients\aa\SD C3 upgrade.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1 0.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1.0.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW aatel v1.1.doc"/> <File Name="C:\MyDocs\Clients\aa\aa findings and recommendations.doc"/> <File Name="C:\MyDocs\Clients\aa\aa RFC - sample.doc"/> <File Name="C:\MyDocs\Clients\aa\aa Risk Change and Issue Log.xls"/> <File Name="C:\MyDocs\Clients\aa\aa schedule.xls"/> <File Name="C:\MyDocs\Clients\aa\aa SD Architecture.vsd"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week1.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week2.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week3.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week4.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week5.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week6.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week7.xls"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\AppDef.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Category.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Link.txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Platform.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Publish.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\revision.txt"/> </Folder>

but I would like it to look like:

<Folder Name="C:\MyDocs\Clients\aa\"> <File Name="C:\MyDocs\Clients\aa\C17232.doc"/> <File Name="C:\MyDocs\Clients\aa\Changes Log.xls"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 3.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 4.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 5.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 6.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 7.doc"/> <File Name="C:\MyDocs\Clients\aa\Project Scope Change.doc"/> <File Name="C:\MyDocs\Clients\aa\SD C3 upgrade.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1 0.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1.0.doc"/> <File Name="C:\MyDocs\Clients\aa\SDO SOW aatel v1.1.doc"/> <File Name="C:\MyDocs\Clients\aa\aa findings and recommendations.doc"/> <File Name="C:\MyDocs\Clients\aa\aa RFC - sample.doc"/> <File Name="C:\MyDocs\Clients\aa\aa Risk Change and Issue Log.xls"/> <File Name="C:\MyDocs\Clients\aa\aa schedule.xls"/> <File Name="C:\MyDocs\Clients\aa\aa SD Architecture.vsd"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week1.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week2.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week3.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week4.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week5.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week6.xls"/> <File Name="C:\MyDocs\Clients\aa\Timesheet Week7.xls"/> </Folder> <Folder Name="C:\MyDocs\Clients\aa\AMO appdef\"> <File Name="C:\MyDocs\Clients\aa\AMO appdef\AppDef.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Category.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Link.txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Platform.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\Publish.Txt"/> <File Name="C:\MyDocs\Clients\aa\AMO appdef\revision.txt"/> </Folder>

the code I am using is:

[code]XmlElement* SearchNode(XmlElement pCurrentRoot, String sFolder)
{
DirectoryIterator iter (sFolder, true, "
.*");

   XmlElement *l_pNode = 0, *l_pNewNode = 0; 
   while(iter.next()) 
   { 
      String l_sPath(iter.getFile().getFullPathName()); 
      if(iter.getFile().isDirectory()) 
      { 
         l_pNode = new XmlElement("Folder"); 
         l_pNode->setAttribute( T("Name"), l_sPath); 

         l_pNewNode = SearchNode(l_pNode, l_sPath);//!!!!!!!THIS IS THE RECURSION!!!!!!! 

         if(l_pNewNode) 
           pCurrentRoot->addChildElement(l_pNewNode); 
      } 
      else 
      { 
         l_pNode = new XmlElement("File"); 
         l_pNode->setAttribute( T("Name"), l_sPath); 
         pCurrentRoot->addChildElement(l_pNode); 
      } 
   } 

   return l_pNode; 

}
[/code]

I guess the problem is with the l_pNewNode but I do not see where or why. any ideas to point me in the right direction would be appreciated.

thanks

Hendry


#17

Sorry. My mistake :slight_smile:

Try this one:

void SearchNode(XmlElement *pCurrentRoot, String sFolder)
{
       DirectoryIterator iter (sFolder, true, "*.*");

       XmlElement *l_pNode = 0;
       while(iter.next())
       {
          String l_sPath(iter.getFile().getFullPathName());
          if(iter.getFile().isDirectory())
          {
             l_pNode = new XmlElement("Folder");
             l_pNode->setAttribute( T("Name"), l_sPath);

             SearchNode(l_pNode, l_sPath);//!!!!!!!THIS IS THE RECURSION!!!!!!!

             pCurrentRoot->addChildElement(l_pNode);
          }
          else
          {
             l_pNode = new XmlElement("File");
             l_pNode->setAttribute( T("Name"), l_sPath);
             pCurrentRoot->addChildElement(l_pNode);
          }
       }
} 

My code was a sample just to indicate to you what the recursion really is. I was not sure that it would really work properly. :lol:

But this way you should get the following result:

<Folder Name="C:\MyDocs\Clients\aa\">
  <File Name="C:\MyDocs\Clients\aa\C17232.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Changes Log.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 3.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 4.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 5.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 6.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Project Highlight Report week 7.doc"/>
  <File Name="C:\MyDocs\Clients\aa\Project Scope Change.doc"/>
  <File Name="C:\MyDocs\Clients\aa\SD C3 upgrade.doc"/>
  <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1 0.doc"/>
  <File Name="C:\MyDocs\Clients\aa\SDO SOW Addendum aatel v1.0.doc"/>
  <File Name="C:\MyDocs\Clients\aa\SDO SOW aatel v1.1.doc"/>
  <File Name="C:\MyDocs\Clients\aa\aa findings and recommendations.doc"/>
  <File Name="C:\MyDocs\Clients\aa\aa RFC - sample.doc"/>
  <File Name="C:\MyDocs\Clients\aa\aa Risk Change and Issue Log.xls"/>
  <File Name="C:\MyDocs\Clients\aa\aa schedule.xls"/>
  <File Name="C:\MyDocs\Clients\aa\aa SD Architecture.vsd"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week1.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week2.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week3.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week4.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week5.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week6.xls"/>
  <File Name="C:\MyDocs\Clients\aa\Timesheet Week7.xls"/>
      <Folder Name="C:\MyDocs\Clients\aa\AMO appdef\">
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\AppDef.Txt"/>
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\Category.Txt"/>
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\Link.txt"/>
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\Platform.Txt"/>
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\Publish.Txt"/>
          <File Name="C:\MyDocs\Clients\aa\AMO appdef\revision.txt"/>
      </Folder>
</Folder>

…because the “C:\MyDocs\Clients\aa\AMO appdef” folder is the subfolder of its parent and thus must reside in it. I think it is more logical than what you want to get. :wink:


#18

Hi Ptomaine,

I still get the same results, I believe it is not the code, I actually think your first code might have worked. The problem I think is that the “Directory Iterator” only returns files nad not directory, so doing the isdirectory test is fruitless. I think I need to strip out each files full path and compare to see if it has changed.

Not sure if that is the intended behaviour of the DirectoryIterator.

Thanks for all the assistance guys.


#19

You’re welcome!

Anyway, I’d recommend to use the second version of my code. :wink:


#20

I have it working now with one minor problem that I seem to be printing out the last sub directory twice.

here is what my code looks like now:

[code]void SearchNode(XmlElement pCurrentRoot, String sFolder, File sLogfile)
{
DirectoryIterator iter (sFolder, true, "
.*");
String l_sLastPath, l_sCurrentPath;
l_sLastPath = sFolder;
XmlElement *l_pNode = 0;
while(iter.next())
{
String l_sPath(iter.getFile().getFullPathName());
l_sCurrentPath = l_sPath.upToFirstOccurrenceOf( iter.getFile().getFileName(), false, true );
sLogfile.appendText( "\nLast Path = " + l_sLastPath + "\nCurrent Path = " + l_sCurrentPath );
if(l_sCurrentPath != l_sLastPath)
{
l_pNode = new XmlElement(“Folder”);
l_pNode->setAttribute( T(“Name”), l_sCurrentPath);

         SearchNode(l_pNode, l_sCurrentPath, sLogfile);//!!!!!!!THIS IS THE RECURSION!!!!!!!

         pCurrentRoot->addChildElement(l_pNode);
		 l_sLastPath = l_sCurrentPath;
      }
      else if( l_sCurrentPath == sFolder )
      {
         l_pNode = new XmlElement("File");
         l_pNode->setAttribute( T("Name"), l_sPath);
         pCurrentRoot->addChildElement(l_pNode);
      }
   }

}
[/code]

any ideas?

I change the else to an else if because I was printing everything twice.