ディレクトリとそのディレクトリのサブディレクトリに含まれるすべてのファイルとディレクトリを一覧表示したい。ディレクトリとしてC:\を選択した場合、プログラムは、アクセスしたハードドライブ上のすべてのファイルとフォルダーのすべての名前を取得します。
リストは次のようになります
fd\1.txt fd\2.txt fd\a\ fd\b\ fd\a\1.txt fd\a\2.txt fd\a\a\ fd\a\b\ fd\b\1.txt fd\b\2.txt fd\b\a fd\b\b fd\a\a\1.txt fd\a\a\a\ fd\a\b\1.txt fd\a\b\a fd\b\a\1.txt fd\b\a\a\ fd\b\b\1.txt fd\b\b\a
string[] allfiles = Directory.GetFiles("path/to/dir", "*.*", SearchOption.AllDirectories);
*.*
はファイルに一致するパターンです
ディレクトリも必要な場合は、次のように移動できます。
foreach (var file in allfiles){
FileInfo info = new FileInfo(file);
// Do something with the Folder or just add them to a list via nameoflist.add();
}
Directory.GetFileSystemEntries
は.NET 4.0+に存在し、ファイルとディレクトリの両方を返します。次のように呼び出します:
string[] entries = Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories);
(UnauthorizedAccessException)にアクセスできないサブディレクトリのコンテンツをリストする試みには対応しませんが、ニーズには十分であることに注意してください。
GetDirectories
および GetFiles
メソッドを使用して、フォルダーとファイルを取得します。
SearchOption
AllDirectories
を使用して、サブフォルダー内のフォルダーとファイルも取得します。
public static void DirectorySearch(string dir)
{
try
{
foreach (string f in Directory.GetFiles(dir))
{
Console.WriteLine(Path.GetFileName(f));
}
foreach (string d in Directory.GetDirectories(dir))
{
Console.WriteLine(Path.GetFileName(d));
DirectorySearch(d);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
私は怖いです、GetFiles
メソッドはファイルのリストを返しますが、ディレクトリは返しません。質問のリストから、結果にフォルダーも含めるように求められます。さらにカスタマイズされたリストが必要な場合は、GetFiles
およびGetDirectories
を再帰的に呼び出してみてください。これを試して:
List<string> AllFiles = new List<string>();
void ParsePath(string path)
{
string[] SubDirs = Directory.GetDirectories(path);
AllFiles.AddRange(SubDirs);
AllFiles.AddRange(Directory.GetFiles(path));
foreach (string subdir in SubDirs)
ParsePath(subdir);
}
ヒント:特定の属性を確認する必要がある場合は、FileInfo
およびDirectoryInfo
クラスを使用できます。
ハンドルを返すFindFirstFileを使用してから、FindNextFileを呼び出す関数を再帰的に呼び出すことができます。
しかし、.netフレームワークを使用するときは、管理されていない領域に入る必要があります。
次のコードは、2つのボタン(1つは終了用、もう1つは開始用)を持つフォームで使用します。フォルダブラウザダイアログとファイル保存ダイアログ。コードは以下にリストされ、私のシステムWindows10(64)で動作します:
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Directory_List
{
public partial class Form1 : Form
{
public string MyPath = "";
public string MyFileName = "";
public string str = "";
public Form1()
{
InitializeComponent();
}
private void cmdQuit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void cmdGetDirectory_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
MyPath = folderBrowserDialog1.SelectedPath;
saveFileDialog1.ShowDialog();
MyFileName = saveFileDialog1.FileName;
str = "Folder = " + MyPath + "\r\n\r\n\r\n";
DirectorySearch(MyPath);
var result = MessageBox.Show("Directory saved to Disk!", "", MessageBoxButtons.OK);
Application.Exit();
}
public void DirectorySearch(string dir)
{
try
{
foreach (string f in Directory.GetFiles(dir))
{
str = str + dir + "\\" + (Path.GetFileName(f)) + "\r\n";
}
foreach (string d in Directory.GetDirectories(dir, "*"))
{
DirectorySearch(d);
}
System.IO.File.WriteAllText(MyFileName, str);
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
次の例は、fastest(並列化されていない)方法で、例外を処理するディレクトリツリー内のファイルとサブフォルダをリストします。 SearchOption.AllDirectoriesを使用してDirectory.EnumerateDirectoriesを使用してすべてのディレクトリを列挙する方が高速ですが、UnauthorizedAccessExceptionまたはPathTooLongExceptionがヒットした場合、このメソッドは失敗します。
ジェネリックStackコレクションタイプを使用します。これは後入れ先出し(LIFO)スタックであり、再帰を使用しません。 https://msdn.Microsoft.com/en-us/library/bb513869.aspx から、すべてのサブディレクトリとファイルを列挙し、それらの例外に効果的に対処できます。
public class StackBasedIteration
{
static void Main(string[] args)
{
// Specify the starting folder on the command line, or in
// Visual Studio in the Project > Properties > Debug pane.
TraverseTree(args[0]);
Console.WriteLine("Press any key");
Console.ReadKey();
}
public static void TraverseTree(string root)
{
// Data structure to hold names of subfolders to be
// examined for files.
Stack<string> dirs = new Stack<string>(20);
if (!System.IO.Directory.Exists(root))
{
throw new ArgumentException();
}
dirs.Push(root);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.EnumerateDirectories(currentDir); //TopDirectoryOnly
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.EnumerateFiles(currentDir);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
Console.WriteLine(e.Message);
continue;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
}
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
}
論理的で順序付けられた方法:
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace DirLister
{
class Program
{
public static void Main(string[] args)
{
//with reflection I get the directory from where this program is running, thus listing all files from there and all subdirectories
string[] st = FindFileDir(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
using ( StreamWriter sw = new StreamWriter("listing.txt", false ) )
{
foreach(string s in st)
{
//I write what I found in a text file
sw.WriteLine(s);
}
}
}
private static string[] FindFileDir(string beginpath)
{
List<string> findlist = new List<string>();
/* I begin a recursion, following the order:
* - Insert all the files in the current directory with the recursion
* - Insert all subdirectories in the list and rebegin the recursion from there until the end
*/
RecurseFind( beginpath, findlist );
return findlist.ToArray();
}
private static void RecurseFind( string path, List<string> list )
{
string[] fl = Directory.GetFiles(path);
string[] dl = Directory.GetDirectories(path);
if ( fl.Length>0 || dl.Length>0 )
{
//I begin with the files, and store all of them in the list
foreach(string s in fl)
list.Add(s);
//I then add the directory and recurse that directory, the process will repeat until there are no more files and directories to recurse
foreach(string s in dl)
{
list.Add(s);
RecurseFind(s, list);
}
}
}
}
}
ディレクトリツリー内のサブフォルダーにアクセスできない場合、Directory.GetFilesは停止し、例外をスローして、受信string []にnull値を返します。
ここで、この回答を参照してください https://stackoverflow.com/a/38959208/6310707
ループ内の例外を管理し、フォルダー全体がトラバースされるまで機能し続けます。