views:

413

answers:

4

I am woking in c++. Is there any method to know whether a directory contain a sub directory?

CFileFind seems have to search through total files. It is time consuming if the only subdirectory is at the end of the list and the there are lots of files.

for example: directory A contains 99995 files and one subdirectory at the end of FindNextFile List. had I try 99995 times, then say: yes, it contains subdirectory?

+1  A: 

Whether this can be done very fast is entirely platform-dependent.

On Win32 you use FindFirstFile/FindNextFile or wrappers on top of those like MFC CFileFind and they list items in some order that can't be forced to list directories first.

sharptooth
say, 99995 files and one subdirectory ant the end of FindNextFile List. had I try 99995 times, then say: yes, it contains subdirectory?
Yeap, that's the only way to list directory contents on Win32. That's why opening a folder with many files in Explorer takes so many time.
sharptooth
OMG, a really bad design...
having 99996 files in one folder is also bad, isn't it?
Nick D
We have a solution that operates on a folder with half million files. It takes long to start it (that's the place where the filelist is acquired) but otherwise it works just fine.
sharptooth
Yes :) but I am writing desktop software, I can't consider a customer who put 99996 files in a folder is stupid... Actually I want to give them a faster filesystem tree-view, no matter how may files are in a directory.
Now the tree-view is a bit slow
You could cache filesystem tree-view and update it in background thread.
Kirill V. Lyadvinsky
@jia3ep Yeap, and the filesystem notifications mechanism to only rescan the directory when it changes.
sharptooth
+1  A: 

If you are using the .Net framework you could use Directory.GetDirectories and check is the size of the array is 0. Do not know how if this will give you speed.

If you have control over the directories you could apply a naming convention so that directories that have sub directories are named one way and directories with out sub directories are named another.

Nick
+1  A: 

You can try using the boost filesystem library.

A class by name directory_iterator [ declared in boost/filesystem/operations.hpp ] has many functions which can be used for listing files, finding whether the file is a sub-directory ( is_directory -- I guess this is what you are looking for ) etc..

Refer the following link for more information. link text

It seems you are using MFC [ just saw that you are using CFileFind ], didn't see that earlier. Sorry, Didn't have much info. You may have to use FindFirstFile/FindNextFile.

Narendra N
Many Thank all the same! boost filesystem is useful. I used it when I worked in Linux
I suppose that boost primitives also use FindFirstFile/FindNextFile on Win32. If they don't one could look up how they work and check whether that solution is better.
sharptooth
+2  A: 

Raymond Chen from Microsoft has written a post that probably applies here: Computing the size of a directory is more than just adding file sizes. In essence, he explains that information like the size of a dir cannot be stored in the dir's entry, because different users might have different permissions, possibly making some of the files invisible to them. Therefore, the only way to get the size the user should see is to calculate it upon request from the user.

In your case, the answer probably stems from the same reasoning. The list of directories available to your app can only be determined when your app asks for it, as its view of the root directory might be different than another app's, running with different credentials. Why Windows store directories along with files I don't know, but that's a given.

Since Win32 is as close as you'll get to the file system in user mode, I'd avoid any higher level solutions such as .NET, as it might only simplify the interface. A driver might work quicker, but that out of the scope of my knowledge.

eran