Next Previous Contents

7. file-system directory handling

When we handle file-system directories, we have to call apr_dir_open() at first. By apr_dir_open(), we have an apr_dir_t object. All we can do with apr_dir_t is to scan the directory. The API is apr_dir_read(). Finally, we call apr_dir_close() to close the directory. The prototype declarations are as follows:

/* excerpted from apr_file_info.h */

APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir, 
                                       const char *dirname, 
                                       apr_pool_t *pool);
APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                                       apr_dir_t *thedir);
APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);

The first argument of apr_dir_open() is result argument. By which, we can get a newly created apr_dir_t object. The second argument is directory name. The third argument is memory pool to use.

The first argument of apr_dir_read() is result argument. As mentioned earlier, apr_finfo_t is complete type. Thus, we have to allocate its memory explicitly. apr_dir_read() returns an entry of the directory by apr_finfo_t. The entry is either file or directory. The second argument is bit-wised flag. The flags are defined in apr_file_info.h with APR_FINFO_ prefix, such as APR_FINFO_SIZE, APR_FINFO_TYPE and APR_FINFO_NAME. The third argument is apr_dir_t object to scan.

Here is a sample code:

/* pseudo code about apr_dir_read() */
/* no error checks */
apr_pool_t *mp;
apr_pool_create(&mp, NULL);
const char *dirpath = "/home";/* directory path to scan */
apr_dir_t *dir;
apr_dir_open(&dir, dirpath, mp);/* create the apr_dir_t object */

apr_finfo_t dirent;
apr_dir_read(&dirent, APR_FINFO_DIRENT, dir);/* the apr_finfo_t object filled */
/* dirent is the first entry of the directory.
 * the entry is either file or directory. */

apr_dir_close(dir);

In the sample code above we call apr_dir_read() only once, but we usually call apr_dir_read() multiple times to scan all files under the directory. To scan all files, we just keep calling apr_dir_read() while it returns APR_SUCCESS. Take a look at dir-sample.c about precise usage.

/* pseudo code about apr_dir_read() loop. error checks omitted */
/* typical while loop of apr_dir_read() */
apr_dir_open(&dir, dirpath, mp);
while ((apr_dir_read(&dirent, APR_FINFO_NAME, dir)) == APR_SUCCESS) {
     printf("file name is %s\n", dirent.name);
}
apr_dir_close(dir);

As you can imagine, apr_dir_t object has the current position. Calling apr_dir_read() makes the position move forward. We can rewind the (internal)position by apr_dir_rewind(). All the operations we can do with the position are just these two, moving forward and rewinding.

As you see in dir-sample.c, if you scan directories recursively, you need to call apr_dir_open() recursively.

REMARK: On Unix, apr_dir_read() returns apr_finfo_t object whose apr_file_t::fname is NULL


Next Previous Contents