はかせのラボ

私の頭の中を書いていく雑記ブログです

C# フォルダ操作

あいさつ

どうも、はかせです。
先日こんなアンケートを行いました。

ツール系の記事でどの言語が見たいかというアンケートで
半数以上の方にC#が見たいという意見を頂きました。

なので前回C++でやった操作を
C#で実装してみます。
前回はこちら
hakase0274.hatenablog.com

環境

Windows10
Visualstudio2017
.NET Framework 4.6.1

C#のフォルダ操作系

C#にはフォルダ操作として
・System.IO.Directory
・DirectoryInfo

この二つがあります。

違いは
前者はstaticメソッド
後者はインスタンスメソッド
であるというぐらいです。
なので何か理由がない限りは好みでいいのかなと思います。

この記事では私の好みということで
System.IO.Directoryを使って実装します。

using

using System;
using System.IO;

カレントディレクトリ取得、移動

//取得
Directory.GetCurrentDirectory()
//移動
Directory.SetCurrentDirectory("移動したいフォルダ名やパス")

もはや恒例カレントディレクトリの操作です。
やることはC++と大して変わらず
Directory.GetCurrentDirectory
Directory.SetCurrentDirectory

これらのGet/Setメソッドを呼び出すだけです。

フォルダ生成

//フォルダ生成
Directory.CreateDirectory("フォルダ名orパス")

もうお馴染みですね。
Directory.CreateDirectory
作りたいフォルダ名かパスを入れてあげるだけです。

フォルダ削除

//削除 第二引数にtrue入れないと空しか消せない
Directory.Delete("フォルダ名orパス", true)

削除は
Directory.Deleteです。
名前が直接的でいいですね。

このメソッドは気を付けないといけない点がありまして、
第二引数です。

指定しないorFalseを入れると
空のフォルダしか消せません

true入れても空のフォルダは消えるので
基本true入れとけばいいと思います。

フォルダコピー、移動

//移動
Directory.Move("移動元のフォルダ名orパス", "移動先のフォルダ名orパス");

移動はDirectory.Moveを使います。
これもC++のrename関数とほぼ同じ動きで、
同階層なら改名、異階層なら移動となります。

問題はコピーです。
C++にはfilesystemという神ヘッダーが生まれたことで
メソッド一発でフォルダのコピーができますが、
C#にはフォルダをコピーするというメソッドは
現在(2019/09/04)存在しません

なのでコピーは自作になります。
とりあえず私の自作コピーのコードです。

//ディレクトリのコピー
public static void DirectoryCopy
(
    string sourcePath, //コピー元ファイルパス
    string destinationPath //コピー先ファイルパス
)
{
    //コピー元が無ければエラー
    if (!Directory.Exists(sourcePath)) 
        throw new IOException();
    //コピー先が無ければ新たに作る
    if (!Directory.Exists(destinationPath)) 
    {
        //フォルダのセキュリティ情報取得
        var access = Directory.GetAccessControl(sourcePath);
        Directory.CreateDirectory(destinationPath,access);
    }
    //ファイルをコピー
    foreach(var file in Directory.GetFiles(sourcePath))
    {
        //ファイルコピー先パスを構築
        var copyto = file.Replace(sourcePath, destinationPath);
        File.Copy(file, copyto);
    }
    //フォルダは再帰でコピー
    foreach(var dic in Directory.GetDirectories(sourcePath))
    {
        //フォルダコピー先パスを構築
        var copyto = dic.Replace(sourcePath, destinationPath);
        DirectoryCopy(dic,copyto);
    }
}

やってることは単純です。
・受け取ったパスデータの確認&処理
・コピー元のファイルをコピー先にコピー
・コピー元のフォルダを再帰処理を使いコピー

欲しい情報は基本C#が用意してくれているので
それらをパズルのように組み合わせていけばできます。
(この程度なら用意してくれていてもいいと思うんだけどな)

C++もfilesystemの存在が無ければ
こんな感じの実装をしなくてはいけませんでした。
filesystemマジ神。

フォルダ階層取得

//ファイル階層を取得
Directory.GetFiles("フォルダパス")
//フォルダ階層を取得
Directory.GetDirectories("フォルダパス")

コピーの実装でぬるっとはみ出してましたね。
ファイル階層取得には
Directory.GetFiles
フォルダ階層取得には
Directory.GetDirectoriesを使います。

それぞれstring[]が返ってきますので、
forなりforeachなりで回してやればそのまま取れます。

あとがき

今回はC#でのフォルダ操作でした。
C++と大して変わりませんでしたね。
ぶっちゃけjavapythonその他言語でも
大体こんな感じです。

なんで一個言語触ってみてやってみれば
他の言語でも大体同じ要領でできるようになります。
(そういう意味で言えばアンケートの3つ目に入れた人は真理をついていますね)

とにかくC#はフォルダのコピーを標準実装してくださいorz
毎回毎回自作したりするのめんどいし、
前作ったやつ探すのもめんどくさいんです。

GitHubに上げればいいじゃんって?
・・・・
・・・・
それだ!

というわけでコードはGitHubに上げました。
github.com

それでは今回はこの辺でノシ