試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Vala言語でディレクトリの項目を一覧表示する

ここでは、Vala言語を用いて「ディレクトリを開いて中の項目を一覧表示する」作業についてを扱う。

GLibを用いた方法

関数GLib.Dir.open()によって得られるGLib.Dirオブジェクトを用いてメンバ関数read_name()を呼ぶことにより、そのディレクトリの項目が(戻り値として)1つ取り出される。繰り返し呼び出すことにより次の項目、またその次の項目、...と取り出され、残りの項目がなくなったらnullが返される。「.」や「..」は返されない。
読み込まれる項目を最初のものに戻したいときにはrewind()を呼ぶ。

public static Dir open (string filename, uint _flags = 0) throws FileError;
public weak string read_name ();
public void rewind ();

下は例。引数に指定したディレクトリ内の項目を1行に1つずつ表示する。
[任意]ファイル名: gdirtest.vala

using GLib;

/*
 * valac -o gdirtest gdirtest.vala
 */

namespace GDirTest
{
  class MainClass
  {
    public static int main (string[] args)
    {
      GLib.Dir dir;
      weak string? item = null;
      string dirpath = args[1];
      if (args.length != 2)
      {
        print ("usage: %s [directory]\n", args[0]);
        return 1;
      }
      try
      {
        dir = GLib.Dir.open (dirpath, 0);
        for (;;)
        {
          item = dir.read_name ();
          if (item == null)
            break;
          print ("%s\n", item);
        }
      }
      catch (GLib.FileError e)
      {
        GLib.critical ("Cannot open directory \"%s\"\n(%s)", dirpath, e.message);
        return 1;
      }
      return 0;
    }
  }
}

GIOを用いた方法

GIOのGFileオブジェクト*1GLib.File.new_for_path ()で生成してメンバ関数enumerate_children()ディレクトリの項目を取得してメンバ関数next_file()によりその情報を含むGLib.Fileinfoオブジェクトを取り出すことができる。
取り出したGLib.Fileinfoオブジェクトのメンバ関数get_name()が個別のファイル/ディレクトリ名となる。

(GLib.Fileインターフェース)
public static GLib.File new_for_path (string path);
public abstract GLib.FileEnumerator enumerate_children (string attributes, GLib.FileQueryInfoFlags flags, GLib.Cancellable? cancellable) throws GLib.Error;
(GLib.FileEnumeratorクラス)
public virtual GLib.FileInfo next_file (GLib.Cancellable? cancellable) throws GLib.Error;
(GLib.FileInfoクラス)
public unowned string get_name ();

下は例。これも実行結果は上のGLib.Dirオブジェクトを用いた例と同様。
[任意]ファイル名: enumeratechildrentest.vala

using GLib;

/*
 * valac --pkg gio-2.0 -o enumeratechildrentest enumeratechildrentest.vala
 */

namespace EnumerateChildrenTest
{
  class EnumerateChildrenTest
  {
    public static int main (string[] args)
    {
      string dirpath = args[1];
      if (args.length != 2)
      {
        print ("usage: %s [directory]\n", args[0]);
        return 1;
      }
      GLib.File dir = GLib.File.new_for_path (dirpath);
      try
      {
        GLib.FileEnumerator en = dir.enumerate_children (GLib.FILE_ATTRIBUTE_STANDARD_NAME, GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
        for (;;)
        {
          GLib.FileInfo info = en.next_file (null);
          if (info == null)
            break;
          print ("%s\n", info.get_name ());
        }
      }
      catch (GLib.Error e)
      {
        GLib.critical ("Cannot open directory \"%s\"\n(%s)", dirpath, e.message);
      }
      return 0;
    }
  }
}

参考URL:

使用したバージョン:

  • Vala 0.7.5

*1:.vapiファイルやリファレンスを見るとクラスではなくインターフェースとなっている