📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の2版が非表示)
523行目: 523行目:
<br><br>
<br><br>


== パーミッション ==
== ディレクトリのパーミッション ==
.NET 5以降では、<code>System.IO.FileSystem</code>名前空間に<code>UnixFileMode</code>列挙型が追加された。<br>
Linuxにおいて、ディレクトリのセキュリティ設定は、主に権限 (パーミッション) の設定を通じて行う。<br>
より細かい制御 (ACLの設定等) が必要な場合は、追加のライブラリやシステムコールが必要になる可能性がある。<br>
<br>
<u>.NET 5以降</u>では、<code>System.IO.FileSystem</code>名前空間に<code>UnixFileMode</code>列挙型が追加された。<br>
この列挙型を使用して、UNIX系OSのファイルパーミッションを扱うことができる。<br>
この列挙型を使用して、UNIX系OSのファイルパーミッションを扱うことができる。<br>
<br>
<br>
権限の設定は、I/Oエラーが発生する可能性が高いため、エラーハンドリングを実装することが重要である。<br>
<br>
<u>※注意 1</u><br>
<u>ただし、<code>UnixFileMode</code>プロパティはLinux環境でのみ動作することに注意する。</u><br>
<u>ただし、<code>UnixFileMode</code>プロパティはLinux環境でのみ動作することに注意する。</u><br>
<br>
<br>
<u>※注意 2</u><br>
<u>root権限または適切な権限を持つユーザとして実行する必要がある。</u><br>
<u>そうでない場合、例外UnauthorizedAccessExceptionが発生する可能性がある。</u><br>
<br>
==== パーミッションの取得 ====
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  using System;
  using System;
574行目: 585行目:
       {
       {
           Console.WriteLine($"エラーが発生: {ex.Message}");
           Console.WriteLine($"エラーが発生: {ex.Message}");
      }
    }
}
</syntaxhighlight>
<br>
==== パーミッションの設定 ====
以下の例では、指定したディレクトリのパーミッションを設定している。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          // ディレクトリが存在することを確認
          if (Directory.Exists(directoryPath))
          {
            // ディレクトリのパーミッションを755に設定 (例: 755 - rwxr-xr-x)
            File.SetUnixFileMode(directoryPath, UnixFileMode.UserRead    |
                                                UnixFileMode.UserWrite    |
                                                UnixFileMode.UserExecute  |
                                                UnixFileMode.GroupRead    |
                                                UnixFileMode.GroupExecute |
                                                UnixFileMode.OtherRead    |
                                                UnixFileMode.OtherExecute);
            // 現在のパーミッションを取得して8進数で表示
            UnixFileMode currentMode = File.GetUnixFileMode(directoryPath);
            Console.WriteLine($"現在のパーミッション: {Convert.ToString((int)currentMode, 8)}");
          }
          else
          {
            Console.WriteLine($"ディレクトリ '{directoryPath}' が存在しない");
          }
      }
      catch (UnauthorizedAccessException e)
      {
          Console.WriteLine($"エラー: アクセス権限がない {e.Message}");
      }
      catch (IOException e)
      {
          Console.WriteLine($"エラー: I/O操作中にエラーが発生 {e.Message}");
      }
    }
}
</syntaxhighlight>
<br>
==== 再帰的なパーミッションの設定 ====
以下の例では、再帰的にディレクトリとそのサブディレクトリのパーミッションを設定している。<br>
<br>
<u>※注意</u><br>
<u>再帰的処理では、大規模なディレクトリ構造を扱う場合にスタックオーバーフローする可能性がある。</u><br>
<u>そのような場合は、非再帰的なアプローチや非同期処理を検討する必要がある。</u><br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          SetPermissionsRecursively(directoryPath);
      }
      catch (UnauthorizedAccessException e)
      {
          Console.WriteLine($"エラー: アクセス権限がない {e.Message}");
      }
      catch (IOException e)
      {
          Console.WriteLine($"エラー: I/O操作中にエラーが発生 {e.Message}");
      }
    }
    static void SetPermissionsRecursively(string path)
    {
      // ディレクトリのパーミッションを755に設定 (例: 755 - rwxr-xr-x)
      File.SetUnixFileMode(path, UnixFileMode.UserRead    |
                                  UnixFileMode.UserWrite    |
                                  UnixFileMode.UserExecute  |
                                  UnixFileMode.GroupRead    |
                                  UnixFileMode.GroupExecute |
                                  UnixFileMode.OtherRead    |
                                  UnixFileMode.OtherExecute);
      // サブディレクトリに対して再帰的に処理
      foreach (string subDir in Directory.GetDirectories(path))
      {
          SetPermissionsRecursively(subDir);
      }
      // ファイルのパーミッションも644に設定する場合 (例: 644 - rw-r--r--)
      foreach (string file in Directory.GetFiles(path))
      {
          File.SetUnixFileMode(file, UnixFileMode.UserRead  |
                                    UnixFileMode.UserWrite |
                                    UnixFileMode.GroupRead |
                                    UnixFileMode.OtherRead);
      }
    }
}
</syntaxhighlight>
<br>
==== 再帰的なパーミッションの設定 (非同期処理) ====
以下の例では、非同期処理を使用して、再帰的にディレクトリとそのサブディレクトリのパーミッションを設定している。<br>
大規模なディレクトリ構造を扱う場合は、非同期処理を使用することを推奨する。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
    static async Task Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          await SetPermissionsRecursivelyAsync(directoryPath);
      }
      catch (Exception e)
      {
          Console.WriteLine($"エラーが発生: {e.Message}");
      }
    }
    static async Task SetPermissionsRecursivelyAsync(string path)
    {
      await Task.Run(() =>
      {
          // ディレクトリのパーミッションを755に設定 (例: 755 - rwxr-xr-x)
          File.SetUnixFileMode(path, UnixFileMode.UserRead    |
                                    UnixFileMode.UserWrite    |
                                    UnixFileMode.UserExecute  |
                                    UnixFileMode.GroupRead    |
                                    UnixFileMode.GroupExecute |
                                    UnixFileMode.OtherRead    |
                                    UnixFileMode.OtherExecute);
      });
      // サブディレクトリに対して再帰的に処理
      foreach (string subDir in Directory.GetDirectories(path))
      {
          await SetPermissionsRecursivelyAsync(subDir);
      }
      // ファイルのパーミッションも644に設定する場合 (例: 644 - rw-r--r--)
      foreach (string file in Directory.GetFiles(path))
      {
          await Task.Run(() =>
          {
            File.SetUnixFileMode(file, UnixFileMode.UserRead  |
                                        UnixFileMode.UserWrite |
                                        UnixFileMode.GroupRead |
                                        UnixFileMode.OtherRead);
          });
      }
    }
}
</syntaxhighlight>
<br><br>
== ディレクトリの属性 ==
Linuxでは、Windowsのような詳細な属性 (アーカイブ、システム、隠しファイル等) は限られているが、基本的な属性や時間情報等を取得および設定することができる。<br>
<br>
<code>DirectoryInfo</code>クラスを使用して、ディレクトリの情報や属性にアクセスする。<br>
また、属性の設定には適切な権限が必要であるため、エラーハンドリングが重要となる。<br>
<br>
時間情報 (作成日時、最終アクセス日時、最終更新日時) の変更が可能であるが、これらの操作はファイルシステムの動作に影響を与える可能性があるため、慎重に行う必要がある。<br>
<br>
<code>FileAttributes</code>列挙型を使用して属性を設定するが、Linuxでは一部の属性 (例: ReadOnly) のみが有効である。<br>
<br>
<u>※注意</u><br>
<u>不適切な属性の変更は、システムの動作に影響を与える可能性があるため、ファイルシステムの整合性とセキュリティに注意すること。</u><br>
<br>
==== ディレクトリの属性の取得 ====
以下の例では、Linuxにおいて、ディレクトリの基本的な属性を取得している。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
          if (dirInfo.Exists)
          {
            Console.WriteLine($"ディレクトリ: {dirInfo.FullName}");
            Console.WriteLine($"作成日時: {dirInfo.CreationTime}");
            Console.WriteLine($"最終アクセス日時: {dirInfo.LastAccessTime}");
            Console.WriteLine($"最終更新日時: {dirInfo.LastWriteTime}");
            Console.WriteLine($"属性: {dirInfo.Attributes}");
            // Linuxパーミッションの取得
            UnixFileMode mode = File.GetUnixFileMode(directoryPath);
            Console.WriteLine($"Unixパーミッション: {Convert.ToString((int)mode, 8).PadLeft(4, '0')}");
          }
          else
          {
            Console.WriteLine($"ディレクトリ '{directoryPath}' が存在しない");
          }
      }
      catch (UnauthorizedAccessException e)
      {
          Console.WriteLine($"エラー: アクセス権限がない {e.Message}");
      }
      catch (IOException e)
      {
          Console.WriteLine($"エラー: I/O操作中にエラーが発生 {e.Message}");
      }
    }
}
</syntaxhighlight>
<br>
==== ディレクトリの属性の設定 ====
以下の例では、ディレクトリの属性を設定している。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
          if (dirInfo.Exists)
          {
            // 最終アクセス日時と最終更新日時を設定
            DateTime newTime = DateTime.Now;
            dirInfo.LastAccessTime = newTime;
            dirInfo.LastWriteTime = newTime;
            // 属性を設定(例:読み取り専用)
            dirInfo.Attributes |= FileAttributes.ReadOnly;
            // 更新後の属性を表示
            Console.WriteLine($"最終アクセス日時: {dirInfo.LastAccessTime}");
            Console.WriteLine($"最終更新日時: {dirInfo.LastWriteTime}");
            Console.WriteLine($"属性: {dirInfo.Attributes}");
          }
          else
          {
            Console.WriteLine($"ディレクトリ '{directoryPath}' が存在しない");
          }
      }
      catch (UnauthorizedAccessException e)
      {
          Console.WriteLine($"エラー: アクセス権限がない {e.Message}");
      }
      catch (IOException e)
      {
          Console.WriteLine($"エラー: I/O操作中にエラーが発生 {e.Message}");
      }
    }
}
</syntaxhighlight>
<br>
==== ディレクトリの属性の設定 (非同期処理) ====
以下の例では、非同期処理を使用して、ディレクトリの属性を設定している。<br>
<br>
ネットワークドライブ上での操作等、遅延が予想される特殊な場合では、非同期処理を使用することを推奨する。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
    static async Task Main(string[] args)
    {
      string directoryPath = "/home/user/testdir";
      try
      {
          DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
          if (dirInfo.Exists)
          {
            await Task.Run(() =>
            {
                DateTime newTime = DateTime.Now;
                dirInfo.LastAccessTime = newTime;
                dirInfo.LastWriteTime = newTime;
                dirInfo.Attributes |= FileAttributes.ReadOnly;
            });
          }
          else
          {
            Console.WriteLine($"ディレクトリ '{directoryPath}' が存在しない");
          }
      }
      catch (Exception e)
      {
          Console.WriteLine($"エラーが発生: {e.Message}");
       }
       }
     }
     }