やりたいこと
ファイルが格納されているフォルダの構造を引き継いだ、別名のフォルダを作成したい。
対象のフォルダ構造
- 元フォルダ
フォルダ構造
orig - orig - aaa - ddd - g.txt
| |
| - eee - fff - h.txt
- bbb
|
- ccc - i.txt
- 変化後フォルダ
フォルダ構造
TestDir - orig - aaa - ddd
| |
| - eee - fff
- ccc
ソース
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace testconsole
{
class Program
{
/// <summary>
/// 元ディレクトリの構造を引き継いで別名でディレクトリを作成する
/// </summary>
/// <param name="sourceDir">元ディレクトリ</param>
static void CreateDestDir(string[] sourceDir)
{
// 作成する別名ディレクトリのリスト
List<string> destDir = new List<string>();
// 1つ目の文字列だけ置換するためRegexインスタンス作成
Regex reg = new Regex("orig");
// 取得したパスから重複を抜いてリストに登録
foreach (string dir in sourceDir)
{
// リスト内に既に文字列がある場合はAdd処理を飛ばす
if (destDir.Contains(reg.Replace(dir.Remove(dir.LastIndexOf('\\')), "TestDir", 1)))
continue;
// 最初に出現した文字列をTestDirに置き換える
destDir.Add(reg.Replace(dir.Remove(dir.LastIndexOf('\\')), "TestDir", 1));
}
// ディレクトリの作成
foreach (string dir in destDir)
{
// 取得したパスはエスケープがされている状態なので、そのままディレクトリ作成
Directory.CreateDirectory(dir);
}
}
static void Main(string[] args)
{
// メンバ変数
string directoryPath = @"C:\Users\watame\Desktop\orig";
string searchFileName = "*.txt";
// 対象のフォルダ以下の .txt ファイル一覧を取得
string[] filePaths = Directory.GetFiles(directoryPath, searchFileName, SearchOption.AllDirectories);
// ディレクトリの作成
CreateDestDir(filePaths);
}
}
}
メソッド説明
コメントでほとんど説明を記載してしまったので、メソッドについて特筆すべきことはありません。
フォルダ名の都合上、最初の orig
部分のみ置換して別名に変更したかったので Regex
を利用して、最初に出現する orig
のみを置換しています。
(他にもっと良いやりかたがあると思いますが、自分では見つけられませんでした)
課題
上記のソースではファイルが格納されていないフォルダは作成されません。
ファイルが格納されていないフォルダも作成されるように出来ればと思います。
- 以下の方法で元のディレクトリでファイルが格納されていないフォルダも作成可能です
var orig = @"C:\orig\";
var dest = @"C:\dest\";
System.IO.Directory.EnumerateDirectories(orig, "*", SearchOption.AllDirectories)
.Select(d => d.Replace(orig, dest))
.Where(d => !Directory.Exists(d))
.ToList()
.ForEach(d => Directory.CreateDirectory(d));
参考サイト
変更履歴
- 20170203 ファイルが格納されていないフォルダの作成方法を追記しました。