C# Directory と File (1)

これから、スピードアップの為に、自分がどうだったっけ？と Google に聞くのではなく、一般的に使うものは正確に記憶していこうと思う。
今後、この分類のブログを書いていくときは、質問を先に書いて、後で復習出来るようにしてみたい。私のチームの扱うものから考えると下記のような内容がカバー出来ればかなり早くコーディングが出来そうだ。

* ファイル操作
* リフレクションと、アセンブリの操作
* LINQ
* ネットワークオペレーション (HttpClient, HttpClientFactory)
* SDKの使用 (主に Azure SDK)
* テスティングフレームワーク
* ASP.NET
* データベースアクセス
* 証明書
* コマンドの実行
* IDE (Visual Studio)
* 上記のものに似た内容を Go lang で。

# ファイル・ディレクトリの操作

* ファイルの書き込み、読み込みの方法とそのインターフェイスは？
* ファイルの存在チェックの方法は？
* ファイルのメタデータの取得方法、およびセットの方法は？
* カレントディレクトリの取得
* ディレクトリの取得、作成、移動の方法とそのインターフェイスは？
* ディレクトリの存在チェックの方法は？
* ディレクトリのメタデータの取得方法、およびセットの方法は？
* ディレクトリに含まれる、ファイルおよび、ディレクトリのの取得の方法は？
* サブディレクトリの内容の取得

おそらく上記のことが出来れば十分であろう。これらを何も見ずに書けるようにしてみる。

## ファイルの書き込み、読み込み、およびそのインターフェイス

ファイルの書き込みには２つの方法がある

### StreamWriter

コンストラクタは下記の通り、基本テキストファイルを読み込むもので、デフォルトは、UTF-8 になる。バッファサイズは、デフォルト 1024.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/49c35b22-f23e-787f-f3ec-bacee4307ecf.png)

`StreamWriter` を使うととても簡単に書ける。static `File` クラスを使うことが出来る。`File` クラスのメソッドは、基本的に便利メソッドの集まりと考えてよい。

```csharp
using (var writer = new StreamWriter(fileName))
{
  writer.WriteLine("Hello ");
}
```

もしくは`File.WriteAllText()` でもファイルを書ける。

```csharp
var heredoc = @"This is an overwriten
hello world!
";
 File.WriteAllText(fileName, heredoc);           
```

ここで、ふと思ったのだけど、`Append` モードで書くときはどうするのかな？と思った。

`FileStream` クラスを使うと、Append モードでオープン出来る。


```csharp
byte[] data = new UTF8Encoding(true).GetBytes("Additional text");
using (var fs = new FileStream(fileName, FileMode.Append))
{
   fs.Write(data, 0, data.Length); // We can also use ReadOnlySpan 
}
```
正直めんどい。低レベルのコーディングではこのインターフェイスが使えそう。`Lock`などのメソッドもあるので、おそらくネイティブな使い道だろう。

もっと楽な方法がある。StreamWriter のコンストラクタには、`Stream` を受け付けるものがあるので、それを使って、`Append` モードの `FileStream`を渡してあげればオッケー。簡単である。

```csharp
using(var fs = new FileStream(fileName, FileMode.Append))
using (var writer = new StreamWriter(fs))
{
    writer.Write("more additional line");
}
```

こういうことをしていると、Stream のクラス構造が気になるところ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/5873c9d2-7ef4-3d49-5c72-f4ff014b20b2.png)

[TutorialsTeacher - C# Stream](https://www.tutorialsteacher.com/csharp/csharp-stream-io)より
実際にはもっとたくさんあるが、[System.IO.Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream?view=net-5.0)この程度は覚えておきたい。

* FileStream: 物理的なファイルに、同期もしくは、非同期読み書きを行う
* BufferedStream: 他のストリームに対して、バッファリングレイヤを設けてパフォーマンスを向上させる。継承は出来ない。[Discussion](https://qastack.jp/programming/2030847/best-way-to-read-a-large-file-into-a-byte-array-in-c) [BufferedStream Class](https://docs.microsoft.com/en-us/dotnet/api/system.io.bufferedstream?view=net-5.0)
* NetworkStream:　ネットワークアクセスのストリーム [NetworkStream Class](https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.networkstream?view=net-5.0)
* PipeStream: パイプオペレーションのストリーム [PipeStream Class](https://docs.microsoft.com/en-us/dotnet/api/system.io.pipes.pipestream?view=net-5.0)
* MemoryStream: [MemoryStream Class](https://docs.microsoft.com/en-us/dotnet/api/system.io.memorystream?view=net-5.0) インメモリのストリーム。
* CryptoStream: [CryptoStream Class](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptostream?view=net-5.0)　暗号化用のストリーム

他にも、gzip 用のストリームやデータベース用のものなど様々なものが用意されている。ここでは、オーバービューをとらえる程度で止めておこう。

## ファイルの存在チェックは？

```csharp
if (File.Exists(fileName))
{
    File.Delete(fileName);
}
```

## ファイルのメタデータの取得とセット

```csharp
Console.WriteLine($"Creation Time: {File.GetCreationTimeUtc(fileName)} LastAccessTime: {File.GetLastAccessTimeUtc(fileName)} LastWriteTime: {File.GetLastWriteTimeUtc(fileName)}");
```

```
Creation Time: 4/19/2021 12:48:24 AM LastAccessTime: 4/19/2021 8:04:11 AM LastWriteTime: 4/19/2021 8:04:11 AM
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/7aeb37cf-1f38-443f-cd18-26c954359f18.png)


## カレントディレクトリ

```csharp
Console.WriteLine(Directory.GetCurrentDirectory());
```

調べているうちに、深く潜りすぎたので、一旦ここで、アウトします。

```csharp
        public void Execute()
        {

            Console.WriteLine(Directory.GetCurrentDirectory());
            string fileName = "hello.txt";

            // Clean up the file. 
            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }

            using (var writer = new StreamWriter(fileName))
            {
                writer.WriteLine("Hello ");
            }


            Console.WriteLine($"{fileName}: {File.ReadAllText(fileName)}");

            // Read FileInfo. 
            FileInfo fi = new FileInfo(fileName);
            using (var writer = fi.CreateText())
            {
                writer.WriteLine("World!");
            }

            Console.WriteLine($"{fileName}: {File.ReadAllText(fileName)}");
            var heredoc = @"This is an overwriten
hello world!
";
            File.WriteAllText(fileName, heredoc);
            Console.WriteLine("last one, ");
            Console.WriteLine($"{fileName}: {File.ReadAllText(fileName)}");

            byte[] data = new UTF8Encoding(true).GetBytes("Additional text");
            using (var fs = new FileStream(fileName, FileMode.Append))
            {
                fs.Write(data, 0, data.Length); // We can also use ReadOnlySpan 
            }
            Console.WriteLine("---");
            Console.WriteLine($"{fileName}: {File.ReadAllText(fileName)}");

            using(var fs = new FileStream(fileName, FileMode.Append))
            using (var writer = new StreamWriter(fs))
            {
                writer.Write("more additional line");
            }

            Console.WriteLine("---");
            Console.WriteLine($"{fileName}: {File.ReadAllText(fileName)}");

            Console.WriteLine("--- metadata");
            Console.WriteLine($"Creation Time: {File.GetCreationTimeUtc(fileName)} LastAccessTime: {File.GetLastAccessTimeUtc(fileName)} LastWriteTime: {File.GetLastWriteTimeUtc(fileName)}");
        }
```


```bash:result
hello.txt: World!

last one,
hello.txt: This is an overwriten
hello world!

---
hello.txt: This is an overwriten
hello world!
Additional text
---
hello.txt: This is an overwriten
hello world!
Additional textmore additional line
--- metadata
Creation Time: 4/19/2021 12:48:24 AM LastAccessTime: 4/19/2021 8:04:11 AM LastWriteTime: 4/19/2021 8:04:11 AM

```