[C# 문법] C# 특정 디렉터리 감시하기

목적

  • 오늘은 C# 에서 특정 디렉터리를 감시하는 방법에 대해서 알려 드리려고 합니다.
  • 예를 들어, D:\monitoring 디렉터리가 있고, 해당 디렉터리 안에 SubDirectory 및 SubDirecotry 안에 있는 파일들까지 전부 확인하여 해당 파일을 다른 경로로 Copy 하는 방법까지 연습할 겸 코드 작성 진행해 보았습니다.
  • 바로 작성한 코드 보여 드리겠습니다.

IFileManager 인터페이스 정의

  • 먼저 IFileManager 인터페이스를 정의 하였습니다.
  • 해당 인터페이스 안에는 Watcher 라는 이름을 가진 메서드가 정의되어 있고, 해당 메서드의 역할은 특정 디렉터리를 감시하는 역할을 하는 메서드 입니다.
namespace ConsoleApp1;

public interface IFileManager
{
    public Task<string> Watcher(string monitoringPath);
}
  • 이제 실제 IFileManager 인터페이스를 상속받아서 Watcher 메서드를 구현하는 구현체 클래스를 생성해 보겠습니다.
  • 이름은 FileWatcher.cs 라고 명명 하였습니다.

FileWatcher.cs

  • FileWatcher.cs 에서는 특정 경로 변수인 monitoringPath 의 경로를 감시하여 해당 디렉터리 안에 있는 하위 디렉터리 및 그 안에 있는 여러 파일들을 감지하여 해당 파일 및 디렉터리를 User 가 원하는 위치로 이동하고 최종적으로 SourceDircetory 는 삭제하는 역할이 구현되어 있습니다.
namespace ConsoleApp1;

public class FileWatcher : IFileManager
{
    public async Task<string> Watcher(string monitoringPath)
    {
        List<string> paths = new();
        DirectoryInfo targetPath = new(monitoringPath);
        DirectoryInfo[] dir = targetPath.GetDirectories();

        for (int idx = 0; idx < dir.Length; idx++)
        {
            FindDirectoriesWithFiles(paths, dir[idx]);
        }

        paths = paths.Distinct().ToList();
        string? sourcePath = paths.FirstOrDefault();

        // File Copy to Delete
        if (!String.IsNullOrWhiteSpace(sourcePath))
        {
            string readyPath = await DefectFileCopyToDelete(sourcePath);
            return readyPath;
        }

        return string.Empty;
    }

    private async Task<string> DefectFileCopyToDelete(string sourcePath)
    {
        string[] pathNames = sourcePath!.Split("\\");
        string readyPath = $@"D:\{DateTime.Now:yyyy-MM-dd}\{pathNames[pathNames.Length - 1]}\";

        bool result = await CopyDirectory(sourcePath, readyPath, true);

        if (result == true)
        {
            DirectoryInfo sourceDirectory = new(sourcePath);
            sourceDirectory.Delete(true);
        }

        return readyPath;
    }

    private void FindDirectoriesWithFiles(List<string> paths, DirectoryInfo workingDir)
    {
        if (workingDir.GetFiles().Length > 0)
        {
            paths.Add(workingDir.Parent!.FullName);
        }
        else
        {
            foreach (var childDir in workingDir.GetDirectories())
            {
                FindDirectoriesWithFiles(paths, childDir);
            }
        }
    }

    private Task<bool> CopyDirectory(string sourceDir, string destinationDir, bool recursive)
    {
        var dir = new DirectoryInfo(sourceDir);

        if (!dir.Exists)
        {
            return Task.FromResult(false);
        }

        DirectoryInfo[] dirs = dir.GetDirectories();
        Directory.CreateDirectory(destinationDir);

        foreach (FileInfo file in dir.GetFiles())
        {
            string targetFilePath = Path.Combine(destinationDir, file.Name);
            file.CopyTo(targetFilePath);
        }

        if (recursive)
        {
            foreach (DirectoryInfo subDir in dirs)
            {
                string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
                CopyDirectory(subDir.FullName, newDestinationDir, true);
            }
        }

        return Task.FromResult(true);
    }
}

Program.cs

  • 저 같은 경우에 D:\monitoring 경로를 감시 경로로 설정 하였습니다.
  • 해당 경로 안에 SubDirectory 들이 존재하고, SubDirectory 안에 세부 파일들이 존재한다면 파일이 지정된 경로로 이동됩니다.
  • 만약 SubDirectory 가 존재 하지 않는다면, string.empty를 반환하고 끝납니다.
using ConsoleApp1;

Console.WriteLine("Program Start!!");

IFileManager defectFileWatcher = new FileWatcher();

string monitoringPath = @"D:\monitoring";
var readyPath = await defectFileWatcher.Watcher(monitoringPath);

Console.WriteLine($"{readyPath}");
728x90

'C# > C# 문법' 카테고리의 다른 글

[C#] CQRS 란?  (0) 2022.05.31
[C# 문법] 패턴 일치 - null 검사  (0) 2022.05.26
[C# 문법] C# 로컬 파일 다루기  (0) 2022.05.26
[C# 문법] Nullable 값 형식  (0) 2022.05.22
[C# 문법] Task 클래스 작업 인스턴스화  (0) 2022.05.22

이 글을 공유하기

댓글

Designed by JB FACTORY