ファイルとディレクトリの表示


指定したパスに存在するファイルとフォルダの一覧を、標準出力に表示させてみる。

#include <glib.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
  GDir *dir;
  gchar *currentdir;

  if( argc != 2 ){
    //argv[1]にパスを格納する以外の入力は受け付けない
    g_print( "Usage: ./test directory\n" );
    exit(1);
  }
  //argv[1]に格納された文字列を使う
  currentdir = argv[1];
  //ディレクトリを開く
  dir = g_dir_open(currentdir, 0, NULL);
  //ディレクトリを開けた場合
  if( dir ){
    const gchar *name;
    //開いたディレクトリの中を調べる
    while( name = g_dir_read_name(dir) ){
      gchar *path;
      gboolean is_dir;
      //ファイル名にパスを追加
      path = g_build_filename(currentdir, name, NULL);
      //ディレクトリかどうか調べる
      is_dir = g_file_test(path, G_FILE_TEST_IS_DIR);
      //ディレクトリまたはファイル名を表示
      g_print( "%s\t(%s)\n", name, (is_dir) ? "directory" : "file");
      //g_built_filenameで確保した領域を解放
      g_free( path );
    }
    //ディレクトリを閉じる
    g_dir_close(dir);
  }
  return 0;
}

g_dir_openでディレクトリを開く。第1引数でパスを指定する。 戻り値はディレクトリ構造体で、GDirで宣言された型に格納する。 第3引数はエラー情報だが、エラーの詳細を必要としない時はNULLを指定すれば、 オープン失敗時にNULLが返される。

またディレクトリを閉じる時は、g_dir_closeを使う。

g_dir_read_nameで、開いたディレクトリ内のディレクトリ名またはファイル名を、1つずつ調べる。

g_build_filenameでファイル名用のメモリ領域を確保した上で、ファイル名にパスを追加する。

g_file_testは、ここでは第2引数にG_FILE_TEST_IS_DIRを指定しているので、 ディレクトリかどうかを調べている。他に使える引数は下記の通り。

G_FILE_TEST_EXISTSファイルが存在するか?
G_FILE_TEST_IS_DIRディレクトリか?
G_FILE_TEST_IS_EXECUTABLE実行形式のファイルか?
G_FILE_TEST_IS_REGULARファイルか?
G_FILE_TEST_IS_SYMLINKシンボリックリンクか?


g_file_testの返り値はgboolean型なので、TRUE or FALSEでデータを扱える。

次に標準出力ではなく、ウィンドウ上のリストに表示してみる。

#include <gtk/gtk>
#include <glib.h>
#include <stdlib.h>

GDir *dir;
gchar *currentdir;

void create_model(GtkWidget *treeview)
{
  GtkListStore *store;

  store = gtk_list_store_new(
    2,
    G_TYPE_STRING,
    G_TYPE_STRING
  );

  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store));

  g_object_unref(store);
}

void set_data(GtkWidget *treeview)
{
  GtkListStore *store;
  GtkTreeIter iter;

  store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)));
  gtk_list_store_clear(store);

  if( dir ){
    const gchar *name;
    while( name = g_dir_read_name(dir) ){
      gchar *path;
      gboolean is_dir;
      path = g_build_filename(currentdir, name, NULL);
      is_dir = g_file_test(path, G_FILE_TEST_IS_DIR);
      gtk_list_store_append(store, &iter);
      if( is_dir ){
        gtk_list_store_set(store, &iter,
          0, name,
          1, "directory",
          -1);
      }
      else{
        gtk_list_store_set(store, &iter,
          0, name,
          1, "file",
          -1);
      }
      g_free( path );
    }
    g_dir_close(dir);
  }
}

void append_column_to_treeview(GtkWidget *treeview, const char *title, const int order)
{
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;

  renderer = gtk_cell_renderer_text_new();

  column = gtk_tree_view_column_new_with_attributes(
    title,
    renderer,
    "text", order,
    NULL
  );

  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
}

void create_view(GtkWidget *treeview)
{
  append_column_to_treeview(treeview, "Name", 0);
  append_column_to_treeview(treeview, "File or Directory", 1);
}

int main(int argc, char **argv)
{
  GtkWidget *window, *treeview;

  if( argc != 2 ){
    g_print( "Please input a directory.\n" );
    exit(1);
  }
  currentdir = argv[1];
  dir = g_dir_open(currentdir, 0, NULL);

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Contents of the Directory");
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  treeview = gtk_tree_view_new();

  create_model(treeview);

  set_data(treeview);

  create_view(treeview);

  gtk_container_add(GTK_CONTAINER(window), treeview);
  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

少しだが、ファイルアクセス関数が使えるようになった。


前章  | 目次 |  次章



トップ



/