using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
string[] argumentArray = Environment.GetCommandLineArgs();
if(argumentArray.Length > 1)
{
List<Task<long>> taskList = new List<Task<long>>();
for(int i = 1; i < argumentArray.Length; i++)
{
taskList.Add(GetDirectorySizeAsync(argumentArray[i]));
}
try
{
Task.WaitAll(taskList.ToArray());
}
catch(AggregateException)
{
}
for(int i = 0 ; i < taskList.Count; i++)
{
if(taskList[i].Status == TaskStatus.Faulted)
{
Console.WriteLine($"{argumentArray[i + 1]} 디렉토리가 없습니다.");
}
else
{
Console.WriteLine($"{argumentArray[i + 1]} 디렉토리 크기 : {taskList[i].Result:N0} 바이트");
}
}
}
else
{
Console.WriteLine("구문 에러 : 1개 이상의 디렉토리 경로를 지정해 주시기 바랍니다.");
}
}
#endregion
#region 디렉토리 크기 구하기 (비동기) - GetDirectorySizeAsync(directoryPath)
/// <summary>
/// 디렉토리 크기 구하기 (비동기)
/// </summary>
/// <param name="directoryPath">디렉토리 경로</param>
/// <returns>디렉토리 크기</returns>
private static Task<long> GetDirectorySizeAsync(string directoryPath)
{
if(!Directory.Exists(directoryPath))
{
return Task.FromException<long>(new DirectoryNotFoundException("디렉토리가 없습니다."));
}
else
{
string[] filePathArray = Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories);
if(filePathArray.Length == 0)
{
return Task.FromResult(0L);
}
else
{
return Task.Run
(
() =>
{
long totalFileLength = 0;
Parallel.ForEach
(
filePathArray,
(filePath) =>
{
FileStream fileStream = new FileStream
(
filePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite,
256,
true
);
long fileLength = fileStream.Length;
Interlocked.Add(ref totalFileLength, fileLength);
fileStream.Close();
}
);
return totalFileLength;
}
);
}
}
}
#endregion
}
}