# C# 目录教程

> 原文： [https://zetcode.com/csharp/directory/](https://zetcode.com/csharp/directory/)

C# 目录教程显示了如何使用 C# 中的目录。 在我们的示例中，我们创建目录，删除目录，列出目录或获取其权限。

## 目录定义

目录，也称为文件夹，是在计算机上存储文件的位置。 除文件外，目录还存储其他目录或快捷方式。

在 C# 中，我们可以使用`Directory`或`DirectoryInfo`处理目录。 `Directory`是一个静态类，提供用于处理目录的静态方法。 `DirectoryInfo`的实例提供有关特定目录的信息。

这些类在`System.IO`命名空间中可用。

## C# 创建目录

使用`Directory.CreateDirectory()`方法创建目录。

`Program.cs`

```cs
using System;
using System.IO;

namespace CreatingDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            var dirName = $@"{docPath}\test";

            DirectoryInfo di = Directory.CreateDirectory(dirName);
            Console.WriteLine($"Full name: {di.FullName}, Name: {di.Name}, Parent: {di.Parent}");

            if (Directory.Exists(dirName))
            {
                Console.WriteLine("Directory exists");
            }
            else
            {
                Console.WriteLine("Directory does not exist");
            }
        }
    }
}

```

该示例在用户的`Documents`目录中创建一个新的`test`目录。

```cs
var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

```

我们用`Environment.GetFolderPath()`方法确定`MyDocuments`目录路径。

```cs
var dirName = $@"{docPath}\test";

```

这是要创建的目录的完整路径。

```cs
DirectoryInfo di = Directory.CreateDirectory(dirName);
Console.WriteLine($"Full name: {di.FullName}, Name: {di.Name}, Parent: {di.Parent}");

```

`Directory.CreateDirectory()`创建一个新目录并返回`DirectoryInfo`，它代表指定路径下的目录。 从目录信息对象中，我们打印目录的全名，名称和父目录。

```cs
if (Directory.Exists(dirName))
{
    Console.WriteLine("Directory exists");
}
else
{
    Console.WriteLine("Directory does not exist");
}

```

使用`Directory.Exists()`方法，我们可以确定指定的目录是否存在。

## C# 获取当前目录

`Directory.GetCurrentDirectory()`获取应用的当前工作目录。

`Program.cs`

```cs
using System;
using System.IO;

namespace CurrentDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            var curDir = Directory.GetCurrentDirectory();
            Console.WriteLine(curDir);

            Console.WriteLine(Directory.GetDirectoryRoot(curDir));
        }
    }
}

```

该程序将打印当前的工作目录（运行程序的目录）及其根目录。 根由`Directory.GetDirectoryRoot()`确定。

```cs
$ dotnet run
C:\Users\Jano\Documents\csharp\directory\CurrentDirectory
C:\

```

这是输出。

## C# 删除目录

使用`Directory.Delete()`方法删除目录。

`Program.cs`

```cs
using System;
using System.IO;

namespace DeleteDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var myDir = $@"{docPath}/test3";

            Directory.CreateDirectory(myDir);
            Console.WriteLine(Directory.Exists(myDir));

            Directory.Delete(myDir);
            Console.WriteLine(Directory.Exists(myDir));
        }
    }
}

```

该示例创建一个新目录，检查它的存在，将其删除，最后再次检查它的存在。

```cs
$ dotnet run
True
False

```

This is the output.

## C# 移动目录

`Directory.Move()`移动（重命名）目录。

`Program.cs`

```cs
using System;
using System.IO;

namespace MoveDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            var sourceDir = $@"{docPath}\test";
            var destDir = $@"{docPath}\test2";

            Directory.Move(sourceDir, destDir);
        }
    }
}

```

该示例重命名目录。

```cs
Directory.Move(sourceDir, destDir);

```

`Directory.Move()`方法的参数是：源目录和目标目录。

## C# 列出驱动器

`Directory.GetLogicalDrives()`以`<drive letter>:\`的形式检索计算机上逻辑驱动器的名称。

`Program.cs`

```cs
using System;
using System.IO;

namespace ListDrives
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] drives = Directory.GetLogicalDrives();

            foreach (string drive in drives)
            {
                System.Console.WriteLine(drive);
            }
        }
    }
}

```

该示例列出了计算机上的所有驱动器。

## C# 列出目录

`Directory.GetDirectories()`返回子目录的名称。 子目录可能符合可选的指定条件。

`Program.cs`

```cs
using System;
using System.IO;

namespace ListDirectories
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            string[] myDirs = Directory.GetDirectories(docPath);
            Console.WriteLine("Directories:");

            foreach (var myDir in myDirs)
            {
                Console.WriteLine(myDir);
            }
        }
    }
}

```

该示例列出了指定目录的所有子目录。

在下一个示例中，我们为列出的目录指定一些条件。

`Program.cs`

```cs
using System;
using System.IO;

namespace ListDirectories2
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            Console.WriteLine(docPath);

            string[] myDirs = Directory.GetDirectories(docPath, "w*",
                    SearchOption.TopDirectoryOnly);

            Console.WriteLine("Directories:");

            foreach (var myDir in myDirs)
            {
                Console.WriteLine(myDir);
            }
        }
    }
}

```

该示例列出了所有以`w`字符开头的目录。

```cs
string[] myDirs = Directory.GetDirectories(docPath, "w*", SearchOption.TopDirectoryOnly);

```

`Directory.GetDirectories()`的第一个参数是要列出的目录。 第二个参数是与要列出的子目录名称匹配的搜索字符串。 第三个参数指定搜索操作应包含所有子目录还是仅包含当前目录。

## C# 列出文件

`Directory.GetFiles()`返回符合（可选）条件的文件名。

`Program.cs`

```cs
using System;
using System.IO;

namespace ListFiles
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            string[] myFiles = Directory.GetFiles(docPath);
            Console.WriteLine("Files:");

            foreach (var myFile in myFiles)
            {
                Console.WriteLine(myFile);
            }
        }
    }
}

```

该示例列出了用户`Documents`目录中的所有文件。

## C# 目录时间

`Directory.GetCreationTime()`获取目录的创建日期和时间。 `Directory.GetLastAccessTime()`获取上次访问指定文件或目录的日期和时间。 `Directory.GetLastWriteTime()`获取指定文件或目录的最后写入日期和时间。

`Program.cs`

```cs
using System;
using System.IO;

namespace GetTimes
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            var myDir = $@"{docPath}\test";

            var creationTime = Directory.GetCreationTime(myDir);
            var lastAccessTime = Directory.GetLastAccessTime(myDir);
            var lastWriteTime = Directory.GetLastWriteTime(myDir);

            Console.WriteLine($"Creation time: {creationTime}");
            Console.WriteLine($"Last access time: {lastAccessTime}");
            Console.WriteLine($"Last write time: {lastWriteTime}");
        }
    }
}

```

该示例打印指定目录的创建时间，上次访问时间和上次写入时间。

## C# 列出条目

`Directory.GetFileSystemEntries()`返回满足指定条件的所有文件和子目录的名称。

`Program.cs`

```cs
using System;
using System.IO;

namespace ListEntries
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            string[] entries = Directory.GetFileSystemEntries(docPath, "w*");
            Console.WriteLine("Entries:");

            foreach (var entry in entries)
            {
                Console.WriteLine(entry);
            }
        }
    }
}

```

该程序列出了指定目录中的所有条目。 条目必须以`w`字符开头。

## C# 目录大小

在下面的示例中，我们确定目录的大小。

`Program.cs`

```cs
using System;
using System.IO;

namespace DirectorySize
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            long size = 0;
            var myDir = $@"{docPath}/csharp";

            var dirInfo = new DirectoryInfo(myDir);

            foreach (FileInfo fi in dirInfo.GetFiles("*", SearchOption.AllDirectories))
            {
                size += fi.Length;
            }

            Console.WriteLine($"The directory size: {size} bytes");
        }
    }
}

```

要获取目录的大小，我们使用`DirectoryInfo`的`GetFiles()`方法。 它返回`FileInfo`类型的数组。 `FileInfo`的`Length`属性检索文件的大小。

```cs
foreach (FileInfo fi in dirInfo.GetFiles("*", SearchOption.AllDirectories))
{
    size += fi.Length;
}

```

我们搜索指定目录及其子目录中的所有文件。 我们获取每个检索到的文件的大小并添加它们。

## C# 复制目录

在以下示例中，我们复制目录。

`Program.cs`

```cs
using System;
using System.IO;

namespace CopyDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            var source = @"C:\Users\Jano\Documents\websites";
            var dest = @"C:\Users\Jano\Documents\websites-2";

            DirectoryCopy(source, dest, true);

            Console.WriteLine("Copying finished");
        }

        private static void DirectoryCopy(string source, string dest, bool copySubDirs = true)
        {
            var dir = new DirectoryInfo(source);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    $"Source directory does not exist or could not be found: {source}");
            }

            DirectoryInfo[] dirs = dir.GetDirectories();

            if (!Directory.Exists(dest))
            {
                Directory.CreateDirectory(dest);
            }

            FileInfo[] files = dir.GetFiles();

            foreach (FileInfo file in files)
            {
                string tempPath = Path.Combine(dest, file.Name);
                file.CopyTo(tempPath, false);
            }

            if (copySubDirs)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string tempPath = Path.Combine(dest, subdir.Name);
                    DirectoryCopy(subdir.FullName, tempPath, copySubDirs);
                }
            }
        }
    }
}

```

在示例中，我们将目录及其所有子目录复制到新位置。

```cs
var source = @"C:\Users\Jano\Documents\websites";
var dest = @"C:\Users\Jano\Documents\websites-2";

```

我们定义源目录和目标目录。

```cs
DirectoryCopy(source, dest, true);

```

复制委托给`DirectoryCopy()`方法。 第三个参数确定是否也复制子目录。

```cs
var dir = new DirectoryInfo(source);

if (!dir.Exists)
{
    throw new DirectoryNotFoundException(
        $"Source directory does not exist or could not be found: {source}");
}

```

我们从源路径创建一个`DirectoryInfo`对象。 如果目录不存在，我们抛出`DirectoryNotFoundException`。

```cs
DirectoryInfo[] dirs = dir.GetDirectories();

```

我们使用`GetDirectories()`方法获取所有顶级目录。

```cs
if (!Directory.Exists(dest))
{
    Directory.CreateDirectory(dest);
}

```

如果目标目录不存在，我们将创建它。

```cs
FileInfo[] files = dir.GetFiles();

foreach (FileInfo file in files)
{
    string tempPath = Path.Combine(dest, file.Name);
    file.CopyTo(tempPath, false);
}

```

我们将文件放在目录中，然后将其复制到新位置。

```cs
if (copySubDirs)
{
    foreach (DirectoryInfo subdir in dirs)
    {
        string tempPath = Path.Combine(dest, subdir.Name);
        DirectoryCopy(subdir.FullName, tempPath, copySubDirs);
    }
}

```

如果设置了`copySubDirs`，我们会将子目录及其内容复制到新位置。 我们递归调用`DirectoryCopy()`方法。

## C# 目录访问控制列表

访问控制列表（ACL）是访问控制条目（ACE）的列表。 ACL 中的每个 ACE 都标识一个受托者，并指定允许，拒绝或审核该受托者的访问权限。

`DirectoryInfo` `GetAccessControl()`方法获取当前目录的访问控制列表（ACL）条目。

```cs
$ dotnet add package System.IO.FileSystem.AccessControl

```

我们需要添加`System.IO.FileSystem.AccessControl`包。

`Program.cs`

```cs
using System;
using System.IO;
using System.Security.AccessControl;

namespace DirectoryACL
{
    class Program
    {
        static void Main(string[] args)
        {
            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var myDir = $@"{docPath}\test";

            var dirInfo = new DirectoryInfo(myDir);
            DirectorySecurity dSecurity = dirInfo.GetAccessControl();
            AuthorizationRuleCollection acl = dSecurity.GetAccessRules(true, true,
                typeof(System.Security.Principal.NTAccount));

            foreach (FileSystemAccessRule ace in acl)
            {
                Console.WriteLine("Account: {0}", ace.IdentityReference.Value);
                Console.WriteLine("Type: {0}", ace.AccessControlType);
                Console.WriteLine("Rights: {0}", ace.FileSystemRights);
                Console.WriteLine("Inherited: {0}", ace.IsInherited);

                Console.WriteLine("------------------------");
            }
        }
    }
}

```

该示例显示指定目录的 ACL。

```cs
var dirInfo = new DirectoryInfo(myDir);

```

创建一个`DirectoryInfo`对象。

```cs
DirectorySecurity dSecurity = dirInfo.GetAccessControl();

```

`GetAccessControl()`方法返回一个`DirectorySecurity`对象，该对象封装了目录的访问控制规则。

```cs
AuthorizationRuleCollection acl = dSecurity.GetAccessRules(true, true,
        typeof(System.Security.Principal.NTAccount));

```

我们使用`GetAccessRules()`方法获得了一组安全规则。

```cs
foreach (FileSystemAccessRule ace in acl)
{
    Console.WriteLine("Account: {0}", ace.IdentityReference.Value);
    Console.WriteLine("Type: {0}", ace.AccessControlType);
    Console.WriteLine("Rights: {0}", ace.FileSystemRights);
    Console.WriteLine("Inherited: {0}", ace.IsInherited);

    Console.WriteLine("------------------------");
}

```

我们在一个`foreach`循环中枚举访问控制规则。

在本教程中，我们使用了 C# 中的目录。

阅读 [C# 教程](/lang/csharp/)或列出[所有 C# 教程](/all/#csharp)。