2
votes

After getting a DIR * using opendir(), I need to use readdir() to read and store the struct dirent into an array.

In order to figure out the size of the array, I could just loop through and count the entries. Then, I could allocate the array and then loop through again to read and store the struct dirent.

However, I'm wondering whether there is a better way to get the number of dir entries?

1
You could allocate a small array, and then use realloc to grow it as necessary.pat
Iirc on some systems the size of a directory (as in, struct stat.st_size) was an indication of the number of entries, but 1. on some systems, it's definitely not portable, and 2. I'm not sure if the number was reduced on file deletion, so I guess the answer to your question is basically "no, sorry"loreb
Iterating twice through the entries seems like a bad idea to me. What happens if a file is created in between the two passes?kolrabi

1 Answers

1
votes

The realloc way is probably the best way to go. Here's an example (small allocation size chosen for demo purposes.) No error checking performed. At the end of the loop, direntArray has the goods, and count tells you how many there are.

#define num_to_alloc 10

int main(int argc, const char * argv[])
{

    struct dirent *direntArray = NULL;

    DIR *myDir = opendir("/tmp");
    int count = 0;
    int max = 0;
    struct dirent *myEnt;

    while ((myEnt = readdir(myDir))){
        if ( count == max ){
            max += num_to_alloc;
            direntArray = realloc(direntArray, max * sizeof(struct dirent));
        }
        memcpy(&direntArray[count], myEnt, sizeof(struct dirent));
        count++;
    }
    return 0; 
}