フォルダ以下にあるフォルダ/ファイルを列挙する

 フォルダ以下にあるフォルダやファイルの情報を取得してみましょう。

 System.IOのDirectoryクラスを使用する

 System.IOのDirectoryクラスを使用してみます。例として"C:\Python27"以下のフォルダを列挙するスクリプトを組んで見ます。

import System
from System.IO import Directory

for folder in Directory.EnumerateDirectories("C:\\Python27"):
  print folder

raw_input()

出力画面
 C:\Python27\DLLs
 C:\Python27\Doc
 C:\Python27\include
 C:\Python27\Lib
 C:\Python27\libs
 これは指定したフォルダ直下のフォルダだけですね。そこでSearchOptionというものを使います。SearchOptionには以下のように2種類の設定が出来ます。

 TopDirectoryOnly ・・・直下のフォルダのみ対象。
 AllDirectories ・・・直下のフォルダとすべてのサブフォルダが対象


通常何も指定しない場合は、TopDirectoryOnlyが設定されています。試しにやってみましょう。

import System
from System.IO import Directory, SearchOption

for folder in Directory.EnumerateDirectories("C:\\Python27", "*",
                       SearchOption.AllDirectories):
  print folder

raw_input()

出力画面:
 C:\Python27\DLLs
 C:\Python27\Doc
 C:\Python27\include
 C:\Python27\Lib
 C:\Python27\libs
 C:\Python27\Lib\bsddb
 C:\Python27\Lib\compiler
 C:\Python27\Lib\ctypes
 C:\Python27\Lib\curses
 C:\Python27\Lib\distutils
 C:\Python27\Lib\email
 C:\Python27\Lib\encodings
 C:\Python27\Lib\hotshot
 C:\Python27\Lib\importlib
 C:\Python27\Lib\json
 C:\Python27\Lib\lib-tk
 C:\Python27\Lib\lib2to3
 C:\Python27\Lib\logging
 C:\Python27\Lib\msilib
 C:\Python27\Lib\multiprocessing
 C:\Python27\Lib\pydoc_data
 C:\Python27\Lib\site-packages
 C:\Python27\Lib\sqlite3
 C:\Python27\Lib\test
 C:\Python27\Lib\unittest
 C:\Python27\Lib\wsgiref
 C:\Python27\Lib\xml
 C:\Python27\Lib\ctypes\macholib
 C:\Python27\Lib\distutils\command
 C:\Python27\Lib\email\mime
 C:\Python27\Lib\lib-tk\test
 C:\Python27\Lib\lib-tk\test\test_tkinter
 C:\Python27\Lib\lib-tk\test\test_ttk
 C:\Python27\Lib\lib2to3\fixes
 C:\Python27\Lib\lib2to3\pgen2
 C:\Python27\Lib\lib2to3\tests
 C:\Python27\Lib\lib2to3\tests\data
 C:\Python27\Lib\lib2to3\tests\data\fixers
 C:\Python27\Lib\lib2to3\tests\data\fixers\myfixes
 C:\Python27\Lib\multiprocessing\dummy
 C:\Python27\Lib\test\crashers
 C:\Python27\Lib\test\decimaltestdata
 C:\Python27\Lib\test\leakers
 C:\Python27\Lib\test\xmltestdata
 C:\Python27\Lib\xml\dom
 C:\Python27\Lib\xml\etree
 C:\Python27\Lib\xml\parsers
 C:\Python27\Lib\xml\sax
では次にファイルを列挙してみましょう。

import System
from System.IO import Directory

for file in Directory.EnumerateFiles("C:\\Python27"):
  print file

raw_input()

出力画面:
 C:\Python27\LICENSE.txt
 C:\Python27\NEWS.txt
 C:\Python27\python.exe
 C:\Python27\pythonw.exe
 C:\Python27\README.txt
 C:\Python27\w9xpopen.exe
 EnumerateFilesメゾットでも、もちろんSearchOptionは使えます。今回はいっぱい出力が出るのが分かっているので省略させてください。

 System.IOのDirectoryInfoクラスを使用する

 今度はSystem.IOのDirectoryInfoクラスを使用して同じことをやってみましょう。

import System
from System.IO import DirectoryInfo

di = DirectoryInfo("C:\\Python27")
for folder in di.EnumerateDirectories():
  print folder.FullName

raw_input()

出力画面
 C:\Python27\DLLs
 C:\Python27\Doc
 C:\Python27\include
 C:\Python27\Lib
 C:\Python27\libs
 DirectoryInfoクラスを使ってももちろん結果は一緒ですが、過程が若干違います。Directoryクラスを使用したときは、文字列の形でパス名しか入手されなかったですがEnumerateDirectoriesメゾットの戻り値がDirectoryInfoオブジェクトで返されています。
 つまり得られたフォルダの情報量が違います。今回はDirectoryクラスに合わせて、FullNameしか使いませんでしたが、DirectoryInfoクラスを使用した方がいろいろ応用することが出来ます。

 ファイルの列挙でも同じで、EnumerateFilesはFileInfoを返します。次の例では、すべてのサブフォルダも検索しますが、検索ターゲットを"*.txt"に限定して実行したものです。

import System
from System.IO import DirectoryInfo, SearchOption

di = DirectoryInfo("C:\\Python27")
for fi in di.EnumerateFiles("*.txt",SearchOption.AllDirectories):
  print fi.FullName

raw_input()

出力画面:
 C:\Python27\LICENSE.txt
 C:\Python27\NEWS.txt
 C:\Python27\README.txt
 C:\Python27\Lib\lib2to3\Grammar.txt
 C:\Python27\Lib\lib2to3\PatternGrammar.txt
 C:\Python27\Lib\site-packages\README.txt
 C:\Python27\Lib\test\leakers\README.txt

 GetDirectoriesメゾットとの違い

 Microsoftのホームページなどで同じようなことが出来るGetDirectotiesメゾットの説明も載っています。EnumerateDirectoriesとGetDirectoriesの違いについて説明します。

 EnumerateDirectoriesを使用すると、全部の検索が終わる前に、DirectoryInfoオブジェクトを返し始めますが、GetDirectoriesを使用すると、全部検索が終わってから、DirectoryInfoオブジェクトを返します。 したがって、多くのファイルおよびディレクトリで作業している場合は、EnumerateDirectories の方が効率がよいことがあります。