最終的にはこれ

func IsEmpty(name string) (bool, error) {
    f, err := os.Open(name)
    if err != nil {
        return false, err
    }
    defer f.Close()

    _, err = f.Readdirnames(1) // Or f.Readdir(1)
    if err == io.EOF {
        return true, nil
    }
    return false, err // Either not empty or error, suits both cases
}

つまり

  • システムにはディレクトリが空かどうかの情報は無いからディレクトリの子があるかどうかで判断するしか無い
  • File.Readdirnames() が最速

以下日本語要約

ディレクトリが空であるか否かは、その名前、作成時間、またはそのサイズ(ファイルの場合)のようなファイルシステムレベルのプロパティとして保存されていません。

つまり、os.FileInfoからこの情報を直接取得することはできません。最も簡単な方法は、ディレクトリの子(内容)をクエリすることです。

ioutil.ReadDir()はあまり良い選択ではありません。なぜなら、これはまず指定されたディレクトリのすべての内容を読み取り、それらを名前でソートし、その後スライスを返すからです。最も速い方法はDave Cが言及したように、File.Readdir()または(好ましくは)File.Readdirnames()を使用してディレクトリの子をクエリすることです。

File.Readdir()とFile.Readdirnames()の両方は、返される値の数を制限するために使用されるパラメータを取ります。1つの子をクエリするだけで十分です。Readdirnames()は名前のみを返すので、FileInfo構造体を取得(および構築)するためのさらなる呼び出しが必要ないため、速度が速くなります。

ディレクトリが空の場合、io.EOFがエラーとして返され(空のスライスやnilのスライスではない)ため、返された名前のスライスは必要ありません。

以下抜粋

Whether a directory is empty or not is not stored in the file-system level as properties like its name, creation time or its size (in case of files).

That being said you can’t just obtain this information from an os.FileInfo. The easiest way is to query the children (content) of the directory.

ioutil.ReadDir() is quite a bad choice as that first reads all the contents of the specified directory and then sorts them by name, and then returns the slice. The fastest way is as Dave C mentioned: query the children of the directory using File.Readdir() or (preferably) File.Readdirnames() .

Both File.Readdir() and File.Readdirnames() take a parameter which is used to limit the number of returned values. It is enough to query only 1 child. As Readdirnames() returns only names, it is faster because no further calls are required to obtain (and construct) FileInfo structs.

Note that if the directory is empty, io.EOF is returned as an error (and not an empty or nil slice) so we don’t even need the returned names slice.

The final code could look like this:

Refs