Re: gtk-list Digest, Vol 86, Issue 9



Hi Phong,

On Mon, 6 Jun 2011 15:52:12 -0400 you wrote:
> Thank you Victor! I have written a recursive function to read all the
> directories and files.
> 
> #include <gtk/gtk.h>
> 
> void read_all_files(const gchar* file) {
>   GDir *dir = g_dir_open(file, 0, NULL);
> 
>   while ((file = g_dir_read_name(dir))) {
>     if (!g_file_test(file, G_FILE_TEST_IS_DIR)) {
>       g_print("%s was opened\n", file);
>     }
>     else {
>       read_all_files(file);
>     }
>   }
> }
> 
> However, it seems that this function still only reads the 1st level of
> subdirectory and print out all the files there and not reading any file at
> 2nd, 3rd, 4th, etc... levels.

Yes, and for a reason that should be fairly obvious if you look at the output.

When you call g_dir_open at the top level, you pass it a PATH to the directory, either relative to CWD or absolute. When it finds a file in there it prints only the name of the file, not its full path. So why would you expect the recursive call to work? The directories it finds in /home/me/test/files aren't present in /home/me/test so of course it won't find them.

If you call this with the result of a gtk file chooser, that will be an absolute path. When you find a directory and recurse into it, you need to combine the directory name "file" (that is, the local file not the argument passed in - bad practice reusing the name like that) with the path where it lives (which is the original "file" that you've overwritten - told you it was bad practice!)

You've also failed to clean up after yourself like the manual tells you to.

The corrected version of your function would be:

void read_all_files ( const gchar* path )    // Note the name change
{
  const gchar * file;		// Note that you need a local pointer var
  GDir *dir = g_dir_open ( path, 0, NULL );

  while ((file = g_dir_read_name(dir)))
  {
    if (!g_file_test(file, G_FILE_TEST_IS_DIR))
    {
      g_print("%s was opened\n", file);
    }
    else
    {
      // New code to create the full path to this subdirectory
      gchar * newpath = g_build_filename ( path, file, NULL );
      read_all_files(newpath);
      g_free ( newpath );
    }
  }
  // And the clean-up code you forgot
  g_dir_close ( dir );
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]