ディレクトリを介してファイルを再帰的に検索する次のコードがあり、すべてのxmlファイルのリストが返されます。ルートディレクトリ内のxmlファイルがリストに含まれていないことを除いて、すべて正常に機能します。
最初に行うのはルートのディレクトリを取得し、次にファイルを取得することであるため、ルートのGetFiles()呼び出しが欠落している理由を理解しています。 foreachの前にGetFiles()呼び出しを含めてみましたが、結果は期待どおりではありません。
public static ArrayList DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, "*.xml"))
{
string extension = Path.GetExtension(f);
if (extension != null && (extension.Equals(".xml")))
{
fileList.Add(f);
}
}
DirSearch(d);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return fileList;
}
私のディレクトリ構造は次のようなものです:
RootDirectory
test1.0.xml
test1.1.xml
test1.2.xml
2ndLevDir
test2.0.xml
test2.1.xml
3rdLevDir
test3.0.xml
test3.1.xml
コードの戻り値:
test2.0.xml
test2.1.xml
test3.0.xml
test3.1.xml
以下を含むすべてのファイルを返したい:
test1.0.xml
test1.1.xml
test1.2.xml
再帰ではあまりよくありません。どんなポインタでも大歓迎です。
Directory.GetFilesのこのオーバーロード を使用して、サブディレクトリを検索できます。例:
string[] files = Directory.GetFiles(sDir, "*.xml", SearchOption.AllDirectories);
そのように検索できる拡張子は1つだけですが、次のようなものを使用できます。
var extensions = new List<string> { ".txt", ".xml" };
string[] files = Directory.GetFiles(sDir, "*.*", SearchOption.AllDirectories)
.Where(f => extensions.IndexOf(Path.GetExtension(f)) >= 0).ToArray();
必要な拡張子を持つファイルを選択します(拡張子の大文字と小文字が区別されるN.B.)。
Directory.EnumerateFiles Method を使用してファイルを列挙することが望ましい場合があります。
foreach(string f in Directory.EnumerateFiles(sDir, "*.xml", SearchOption.AllDirectories))
{
// do something
}
適切なアクセス許可を持たないアカウントでコードが実行されている場合、UnauthorizedAccessExceptionなど、スローされる可能性がある例外については、ドキュメントを参照してください。
これにより、すべてのxmlファイルが再帰的に返されます。
var allFiles = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories);
次の方法を試してください。
public static IEnumerable<string> GetXMLFiles(string directory)
{
List<string> files = new List<string>();
try
{
files.AddRange(Directory.GetFiles(directory, "*.xml", SearchOption.AllDirectories));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return files;
}
1つを使用する代わりに、3つのリストを作成しています(DirSearch(d)
の戻り値は使用しません)。リストをパラメーターとして使用して、状態を保存できます。
static void Main(string[] args)
{
var list = new List<string>();
DirSearch(list, ".");
foreach (var file in list)
{
Console.WriteLine(file);
}
}
public static void DirSearch(List<string> files, string startDirectory)
{
try
{
foreach (string file in Directory.GetFiles(startDirectory, "*.*"))
{
string extension = Path.GetExtension(file);
if (extension != null)
{
files.Add(file);
}
}
foreach (string directory in Directory.GetDirectories(startDirectory))
{
DirSearch(files, directory);
}
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
ディレクトリのループの前または後にファイルのループを作成する必要がありますが、これまでのようにファイル内にネストすることはできません。
foreach (string f in Directory.GetFiles(d, "*.xml"))
{
string extension = Path.GetExtension(f);
if (extension != null && (extension.Equals(".xml")))
{
fileList.Add(f);
}
}
foreach (string d in Directory.GetDirectories(sDir))
{
DirSearch(d);
}
次のようなことができます:
foreach (var file in Directory.GetFiles(MyFolder, "*.xml", SearchOption.AllDirectories))
{
// do something with this file
}
フォルダーのループの外側にファイルのループを移動する必要があります。さらに、ファイルのコレクションを保持するデータ構造をメソッドの各呼び出しに渡す必要があります。これにより、すべてのファイルが単一のリストに入れられます。
public static List<string> DirSearch(string sDir, List<string> files)
{
foreach (string f in Directory.GetFiles(sDir, "*.xml"))
{
string extension = Path.GetExtension(f);
if (extension != null && (extension.Equals(".xml")))
{
files.Add(f);
}
}
foreach (string d in Directory.GetDirectories(sDir))
{
DirSearch(d, files);
}
return files;
}
次に、このように呼び出します。
List<string> files = DirSearch("c:\foo", new List<string>());
更新:
とにかく他の答えを読むまで、これを行うための組み込みのメカニズムが既にあります。コードを機能させるためにどのようにコードを変更する必要があるかを知りたい場合は、回答を残します。
EnumerateFilesを使用して、ネストされたディレクトリ内のファイルを取得します。 AllDirectoriesを使用して、ディレクトリ全体を再帰します。
using System;
using System.IO;
class Program
{
static void Main()
{
// Call EnumerateFiles in a foreach-loop.
foreach (string file in Directory.EnumerateFiles(@"c:\files",
"*.xml",
SearchOption.AllDirectories))
{
// Display file path.
Console.WriteLine(file);
}
}
}