Bir dizindeki + alt dizinlerdeki tüm dosyaları ve dizinleri listeleyin


109

Bir dizinde bulunan her dosya ve dizini ve o dizinin alt dizinlerini listelemek istiyorum. Dizin olarak C: \ seçersem, program erişebildiği sabit sürücüdeki her dosya ve klasörün her adını alırdı.

Bir liste şöyle görünebilir

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 \ bir
fd b \ b \
fd \ a \ a \ 1.txt
fd \ a \ a \ a \
fd \ a \ b \ 1.txt
fd \ a \ b \ bir
FD \ b \ a \ 1.txt
FD \ b \ a \ a \
fd \ b \ b \ 1.txt
fd \ b \ b \ a

Size yardımcı olabilecek sınıflar ve yöntemler için System.IO ad alanına göz atın .
Lucero

Bu soruyu kontrol edin ve bir desenle eşleştiği kısmı bırakın.
dasblinkenlight 08

Yanıtlar:


192
string[] allfiles = Directory.GetFiles("path/to/dir", "*.*", SearchOption.AllDirectories);

*.*dosyaları eşleştirmek için kalıp nerede

Dizine de ihtiyaç duyulursa, şu şekilde gidebilirsiniz:

 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();
 }

1
Gerçekten işe yaramayacak ... Lsit<>sınıf? GetFiles ne döndürür? Ayrıca istenen dizin isimleri ne olacak?
Lucero

1
GetFilesYöntem, bir dizi dizisi döndürür.
Guffa

aslında ... Doğru ... yanılmıyorsam bir az şey 2 gün önce abaout Qt öğrenme ve oldu ediyorum edilir
Ruslan F.

Bu işe yarayabilir, ancak genellikle bir UnauthorizedAccessException ile başarısız olur. Yalnızca erişebildiği dizinleri nasıl arar?
derp_in_mouth

Bu, sisteminizde bu uygulamanın yeterli izne sahip olmadığı anlamına gelir
Ruslan F.

50

Directory.GetFileSystemEntries.NET 4.0+ sürümünde bulunur ve hem dosyaları hem de dizinleri döndürür. Şöyle diyelim:

string[] entries = Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories);

Erişiminizin olmadığı (UnauthorizedAccessException) alt dizinlerin içeriğini listeleme girişimleriyle baş etmeyeceğini, ancak ihtiyaçlarınız için yeterli olabileceğini unutmayın.


3
Bu, buradaki en iyi cevaptır. Tüm dosya ve klasörleri, diğerlerinin hiçbirinin yapmadığı tek bir kod satırında alır.
Steve Smith

15

Klasörleri ve dosyaları almak için GetDirectoriesve GetFilesyöntemlerini kullanın .

Alt klasörlerdeki klasörleri ve dosyaları da almak için kullanın .SearchOption AllDirectories


Adın sol kısmını kesmek için Alt Dize'yi kullanın . :)
Lucero

@Lucero Bunu nasıl ve neden yaparsınız? Pathdaha güvenilir yöntemler sunar.
Gusdor

@Gusdor Yolun Pathsabit bir sol kısmını kaldırmak için kullanarak daha uygun bir yol önermekten çekinmeyin , örneğin verilen örnekte `` C: ".
Lucero

@Lucero yorumum kötü ifade edildi. 'Alt dizeyi kullan' bana pek bir şey söylemiyor ve güzel bir çözüm bulmak için linqpad'e takılıp kaldım. Örneğin, parametre ne olurdu? path.SubString(2)Sürücü harfini ve iki noktayı saf bir şekilde kaldırmak için yapacak mısınız ? Ya dizin bir ağ paylaşımı ise? PathGüvenilir bir yöntem olarak öneriyorum çünkü bu alanda pek çok güzellik sağlayabilir. Bu durumda yazabilirsiniz filePath.Substring(Path.GetPathRoot(filePath).Length). Evet, bu en özlü olduğu için Alt dize kullanır.
Gusdor

10
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);
    }
}

3
Kodun ne yaptığına dair küçük bir açıklama ekleyebilirseniz cevabınızı iyileştirirsiniz.
Alex

Dizinde özyinelemeli olarak gider ve dosya adlarını veya dizin adlarını yazdırır. Her iç dizin için aynı işlevi çağırır. Daha fazla bilgi için: stackoverflow.com/questions/929276/…
I. Adım

3

Korkarım, GetFilesyöntem dosya listesini döndürür, ancak dizinleri döndürmez. Sorudaki liste, sonucun klasörleri de içermesi gerektiğini söylüyor. Daha özelleştirilmiş bir liste istiyorsanız, aramayı GetFilesve GetDirectoriesyinelemeli olarak deneyebilirsiniz . Bunu dene:

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);
}

İpucu: Herhangi bir özelliği kontrol etmeniz gerekiyorsa FileInfove DirectoryInfosınıflarını kullanabilirsiniz .


1

Bir tutamaç döndüren FindFirstFile'ı kullanabilir ve daha sonra FindNextFile'ı çağıran bir işlevi özyinelemeli olarak çağırabilirsiniz.Bu, başvurulan yapı alternName, lastTmeCreated, değiştirilmiş, öznitelikler gibi çeşitli verilerle doldurulacağından iyi bir yaklaşımdır.

Ancak .net çerçevesini kullandıkça, yönetilmeyen alana girmeniz gerekir.


1

Dizinde aşağı gitmek için maksimum lvl ve klasörleri hariç tutma seçeneği olan bazı geliştirilmiş sürümler:

using System;
using System.IO;

class MainClass {
  public static void Main (string[] args) {

    var dir = @"C:\directory\to\print";
    PrintDirectoryTree(dir, 2, new string[] {"folder3"});
  }


  public static void PrintDirectoryTree(string directory, int lvl, string[] excludedFolders = null, string lvlSeperator = "")
  {
    excludedFolders = excludedFolders ?? new string[0];

    foreach (string f in Directory.GetFiles(directory))
    {
        Console.WriteLine(lvlSeperator+Path.GetFileName(f));
    } 

    foreach (string d in Directory.GetDirectories(directory))
    {
        Console.WriteLine(lvlSeperator + "-" + Path.GetFileName(d));

        if(lvl > 0 && Array.IndexOf(excludedFolders, Path.GetFileName(d)) < 0)
        {
          PrintDirectoryTree(d, lvl-1, excludedFolders, lvlSeperator+"  ");
        }
    }
  }
}

giriş dizini:

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
      file6.txt
  -folder3
    file3.txt
  -folder4
    file4.txt
    file5.txt

işlevin çıktısı (klasör5 içeriği, lvl sınırı nedeniyle hariç tutulur ve klasör3 içeriği, excludedFolders dizisinde olduğu için hariç tutulur):

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
  -folder3
  -folder4
    file4.txt
    file5.txt

0

Dizin ağacının içindeki bir alt klasöre erişiminiz yoksa, Directory.GetFiles durur ve istisna atar ve alıcı dizgede [] boş bir değere neden olur.

Burada, bu yanıta bakın https://stackoverflow.com/a/38959208/6310707

Döngü içindeki istisnayı yönetir ve tüm klasör geçene kadar çalışmaya devam eder.


0

mantıksal ve düzenli yol:

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);
            }
        }
    }
}
}

Lütfen bir açıklama veya satır içi yorumlar sağlar mısınız, kodunuz ne işe yarar?
MarthyM

Tabii ki yaptım, ama kendi kendini açıklayıcı olmalı, tüm dizinler ve dosyalar arasında basit bir döngüsel özyineleme
Sascha

0

Aşağıdaki örnek, istisnaları işleyen bir dizin ağacındaki dosyaları ve alt klasörleri en hızlı (paralelleştirilmemiş) şekilde listeler. Tüm dizinleri numaralandırmak için SearchOption.AllDirectories'i kullanarak Directory.EnumerateDirectories'i kullanmak daha hızlı olur, ancak bir UnauthorizedAccessException veya PathTooLongException'a ulaşırsa bu yöntem başarısız olur.

Son giren ilk çıkar (LIFO) yığın olan ve özyinelemeyi kullanmayan genel Yığın toplama türünü kullanır. Gönderen https://msdn.microsoft.com/en-us/library/bb513869.aspx , tüm alt dizinleri ve dosyaları numaralandırması ve bu istisnalar dışında etkili bir şekilde başa çıkmak için izin verir.

    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);
        }
    }
}

Çok sayıda dosya ve dizin için Görevler mi kullanıyorsunuz?
PreguntonCojoneroCabrón

msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx , bir yığın koleksiyonu kullanan ve daha hızlı olan yukarıdaki çözümün Parallel Threading sürümüdür.
Markus

0

Aşağıdaki kodu, biri çıkış diğeri başlatmak için olmak üzere 2 düğmeli bir formla kullanıyorum. Klasör tarayıcı iletişim kutusu ve dosya kaydetme iletişim kutusu. Kod aşağıda listelenmiştir ve sistemimde çalışır 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);
            }
        }
    }
}

0

Bununla, onları çalıştırabilir ve konsol çalıştırıldığında alt klasörü seçebilirsiniz.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using data.Patcher; // The patcher XML
namespace PatchBuilder
{
class Program
{
    static void Main(string[] args)
    {
        string patchDir;
        if (args.Length == 0)
        {
            Console.WriteLine("Give the patch directory in argument");
            patchDir = Console.ReadLine();
        }
        else
        {
            patchDir = args[0];
        }

        if (File.Exists(Path.Combine(patchDir, "patch.xml")))
            File.Delete(Path.Combine(patchDir, "patch.xml"));

        var files = Directory.EnumerateFiles(patchDir, "*", SearchOption.AllDirectories).OrderBy(p => p).ToList();

        foreach (var file in files.Where(file => file.StartsWith("patch\\Resources")).ToArray())
        {
            files.Remove(file);
            files.Add(file);
        }

        var tasks = new List<MetaFileEntry>();
        using (var md5Hasher = MD5.Create())
        {
            for (int i = 0; i < files.Count; i++)
            {
                var file = files[i];

                if ((File.GetAttributes(file) & FileAttributes.Hidden) != 0)
                    continue;

                var content = File.ReadAllBytes(file);
                var md5Hasher2 = MD5.Create();

                var task =
                    new MetaFileEntry
                    {
                        LocalURL = GetRelativePath(file, patchDir + "\\"),
                        RelativeURL = GetRelativePath(file, patchDir + "\\"),
                        FileMD5 = Convert.ToBase64String(md5Hasher2.ComputeHash(content)),
                        FileSize = content.Length,
                    };

                md5Hasher2.Dispose();

                var pathBytes = Encoding.UTF8.GetBytes(task.LocalURL.ToLower());
                md5Hasher.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
                if (i == files.Count - 1)
                    md5Hasher.TransformFinalBlock(content, 0, content.Length);
                else
                    md5Hasher.TransformBlock(content, 0, content.Length, content, 0);

                tasks.Add(task);
                Console.WriteLine(@"Add " + task.RelativeURL);
            }

            var patch = new MetaFile
            {
                Tasks = tasks.ToArray(),
                FolderChecksum = BitConverter.ToString(md5Hasher.Hash).Replace("-", "").ToLower(),
            };


            //XmlUtils.Serialize(Path.Combine(patchDir, "patch.xml"), patch);
            Console.WriteLine(@"Created Patch in {0} !", Path.Combine(patchDir, "patch.xml"));
        }

        Console.Read();
    }

    static string GetRelativePath(string fullPath, string relativeTo)
    {
        var foldersSplitted = fullPath.Split(new[] { relativeTo.Replace("/", "\\").Replace("\\\\", "\\") }, StringSplitOptions.RemoveEmptyEntries); // cut the source path and the "rest" of the path

        return foldersSplitted.Length > 0 ? foldersSplitted.Last() : ""; // return the "rest"
    }
}
}

ve bu XML dışa aktarımı için yama

using System.Xml.Serialization;

namespace data.Patcher
{
    public class MetaFile
    {

        [XmlArray("Tasks")]
        public MetaFileEntry[] Tasks
        {
            get;
            set;
        }

        [XmlAttribute("checksum")]
        public string FolderChecksum
        {
            get;
            set;
        }
    }
}

-1
using System.IO;
using System.Text;
string[] filePaths = Directory.GetFiles(@"path", "*.*", SearchOption.AllDirectories);

Cevabınız, halihazırda mevcut en çok oylanan cevaba yeni bir şey eklemiyor.
varsayılan yerel ayar

1
Aynı zamanda yanlış, çünkü bu herhangi bir dizini (soruda belirtildiği gibi), yalnızca gerçek dosyaları döndürmüyor.
Alastair Maw

-1

Biraz basit ve yavaş ama çalışıyor !! Eğer bir dosya yolu vermezseniz, temelde "fixPath" i kullanın, bu sadece bir örnektir .... istediğinizi doğru fileType yazın, liste adını seçtiğimde bir hata yaptım çünkü "temporaryFileList aranan dosya listesidir öyleyse devam edin .... ve "hataListesi" kendi adına konuşuyor

 static public void Search(string path, string fileType, List<string> temporaryFileList, List<string> errorList)
    {

        List<string> temporaryDirectories = new List<string>();

        //string fix = @"C:\Users\" + Environment.UserName + @"\";
        string fix = @"C:\";
        string folders = "";
        //Alap útvonal megadása 
        if (path.Length != 0)
        { folders = path; }
        else { path = fix; }

        int j = 0;
        int equals = 0;
        bool end = true;

        do
        {

            equals = j;
            int k = 0;

            try
            {

                int foldersNumber = 
                Directory.GetDirectories(folders).Count();
                int fileNumber = Directory.GetFiles(folders).Count();

                if ((foldersNumber != 0 || fileNumber != 0) && equals == j)
                {

                    for (int i = k; k < 
                    Directory.GetDirectories(folders).Length;)
                    {

             temporaryDirectories.Add(Directory.GetDirectories(folders)[k]);
                        k++;
                    }

                    if (temporaryDirectories.Count == j)
                    {
                        end = false;
                        break;
                    }
                    foreach (string files in Directory.GetFiles(folders))
                    {
                        if (files != string.Empty)
                        {
                            if (fileType.Length == 0)
                            {
                                temporaryDirectories.Add(files);
                            }
                            else
                            {

                                if (files.Contains(fileType))
                                {
                                    temporaryDirectories.Add(files);

                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                }

                equals++;

                for (int i = j; i < temporaryDirectories.Count;)
                {
                    folders = temporaryDirectories[i];
                    j++;
                    break;
                }

            }
            catch (Exception ex)
            {
                errorList.Add(folders);

                for (int i = j; i < temporaryDirectories.Count;)
                {
                    folders = temporaryDirectories[i];
                    j++;
                    break;
                }
            }
        } while (end);
    }

-1

Dize Listesi Oluştur

    public static List<string> HTMLFiles = new List<string>();

 private void Form1_Load(object sender, EventArgs e)
        {

     HTMLFiles.AddRange(Directory.GetFiles(@"C:\DataBase", "*.txt"));
            foreach (var item in HTMLFiles)
            {
                MessageBox.Show(item);
            }

}

Bu, alt dizinleri almaz.
TidyDev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.