첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ FTPItem.cs

using System;
using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// FTP 항목
    /// </summary>
    public class FTPItem
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 디렉토리 URI - DirectoryURI

        /// <summary>
        /// 디렉토리 URI
        /// </summary>
        public string DirectoryURI { get; set; }

        #endregion

        #region 생성 일자 문자열 - CreateDateString

        /// <summary>
        /// 생성 일자 문자열
        /// </summary>
        public string CreateDateString { get; set; }

        #endregion
        #region 생성 시간 문자열 - CreateTimeString

        /// <summary>
        /// 생성 시간 문자열
        /// </summary>
        public string CreateTimeString { get; set; }

        #endregion
        #region 항목 구분 - ItemType

        /// <summary>
        /// 항목 구분
        /// </summary>
        public string ItemType { get; set; }

        #endregion
        #region 파일 길이 - FileLength

        /// <summary>
        /// 파일 길이
        /// </summary>
        public long FileLength { get; set; }

        #endregion
        #region 파일 길이 문자열 - FileLengthString

        /// <summary>
        /// 파일 길이 문자열
        /// </summary>
        public string FileLengthString { get; set; }

        #endregion
        #region 항목명 - ItemName

        /// <summary>
        /// 항목명
        /// </summary>
        public string ItemName { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 항목 구하기 - GetItem(osType, directoryURI, source)

        /// <summary>
        /// 항목 구하기
        /// </summary>
        /// <param name="osType">운영 체제 타입</param>
        /// <param name="directoryURI">디렉토리 URI</param>
        /// <param name="source">소스 문자열</param>
        /// <returns>파일 항목</returns>
        public static FTPItem GetItem(string osType, string directoryURI, string source)
        {
            if(osType == "WINDOWS")
            {
                #region 운영 체제 타입이 "WINDOWS"인 경우 처리한다.

                try
                {
                    FTPItem item = new FTPItem();

                    item.DirectoryURI = directoryURI;

                    item.CreateDateString = source.Substring( 0, 8);
                    item.CreateTimeString = source.Substring(10, 7);

                    string fileLengthString = source.Substring(24, 14).Trim();

                    if(fileLengthString == "<DIR>")
                    {
                        item.ItemType         = "DIRECTORY";
                        item.FileLength       = 0L;
                        item.FileLengthString = string.Empty;
                    }
                    else
                    {
                        item.ItemType = "FILE";

                        try
                        {
                            item.FileLength       = Convert.ToInt64(fileLengthString);
                            item.FileLengthString = item.FileLength.ToString("#,##0");
                        }
                        catch
                        {
                            item.FileLength       = 0L;
                            item.FileLengthString = string.Empty;
                        }
                    }

                    item.ItemName = source.Substring(39);

                    return item;
                }
                catch
                {
                    return null;
                }

                #endregion
            }
            else if(osType == "UNIX")
            {
                #region 운영 체제 타입이 "UNIX"인 경우 처리한다.

                try
                {
                    string[] sourceItemArray = source.Split(' ');

                    List<string> sourceItemList = new List<string>();

                    foreach(string sourceItem in sourceItemArray)
                    {
                        if(!string.IsNullOrWhiteSpace(sourceItem))
                        {
                            sourceItemList.Add(sourceItem);
                        }
                    }

                    if(sourceItemList.Count != 9)
                    {
                        return null;
                    }

                    if(sourceItemList[8] == "." || sourceItemList[8] == "..")
                    {
                        return null;
                    }

                    FTPItem item = new FTPItem();

                    item.DirectoryURI = directoryURI;

                    if(sourceItemList[7].Contains(":"))
                    {
                        item.CreateDateString = string.Format("{0} {1} {2}", sourceItemList[5], sourceItemList[6], DateTime.Now.Year);
                        item.CreateTimeString = sourceItemList[7];
                    }
                    else
                    {
                        item.CreateDateString = string.Format("{0} {1} {2}", sourceItemList[5], sourceItemList[6], sourceItemList[7]);
                        item.CreateTimeString = string.Empty;
                    }

                    if(sourceItemList[0].StartsWith("d"))
                    {
                        item.ItemType = "DIRECTORY";
                    }
                    else
                    {
                        item.ItemType = "FILE";
                    }

                    try
                    {
                        item.FileLength       = Convert.ToInt64(sourceItemList[4]);
                        item.FileLengthString = item.FileLength.ToString("#,##0");
                    }
                    catch
                    {
                        item.FileLength       = 0L;
                        item.FileLengthString = string.Empty;
                    }

                    item.ItemName = sourceItemList[8];

                    return item;
                }
                catch
                {
                    return null;
                }

                #endregion
            }
            else
            {
                return null;
            }
        }

        #endregion
    }
}

 

728x90

 

▶ FTPHelper.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace TestProject
{
    /// <summary>
    /// FTP 헬퍼
    /// </summary>
    public static class FTPHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 리스트 구하기 - GetList(osType, transportMode, serverAddress, directoryURI, userID, password)

        /// <summary>
        /// 리스트 구하기
        /// </summary>
        /// <param name="osType">운영 체제</param>
        /// <param name="transportMode">전송 모드</param>
        /// <param name="serverAddress">서버 주소</param>
        /// <param name="directoryURI">디렉토리 URI</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        /// <returns>FTP 항목 리스트</returns>
        public static List<FTPItem> GetList(string osType, string transportMode, string serverAddress, string directoryURI, string userID, string password)
        {
            List<FTPItem> list = new List<FTPItem>();

            string targetURI = string.IsNullOrEmpty(directoryURI) ? serverAddress : serverAddress + "/" + directoryURI;

            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetURI);

            request.Credentials = new NetworkCredential(userID, password);
            request.Method      = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.EnableSsl   = transportMode == "SFTP" ? true : false;

            using(FtpWebResponse response = (FtpWebResponse)request.GetResponse())
            {
                Stream stream = response.GetResponseStream();

                using(StreamReader reader = new StreamReader(stream))
                {
                    while(!reader.EndOfStream)
                    {
                        string sourceLine = reader.ReadLine();

                        FTPItem item = FTPItem.GetItem(osType, directoryURI, sourceLine);

                        if(item != null)
                        {
                            list.Add(item);
                        }
                    }
                }
            }

            return list;
        }

        #endregion
        #region 파일 업로드 하기 - UploadFile(transportMode, sourceFilePath, targetURI, userID, password, reportAction)

        /// <summary>
        /// 파일 업로드 하기
        /// </summary>
        /// <param name="transportMode">전송 모드</param>
        /// <param name="sourceFilePath">소스 파일 경로</param>
        /// <param name="targetURI">타겟 URI</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        /// <param name="reportAction">리포트 액션</param>
        public static void UploadFile(string transportMode, string sourceFilePath, string targetURI, string userID, string password, Action<long, long> reportAction = null)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetURI);

            request.Credentials = new NetworkCredential(userID, password);
            request.Method      = WebRequestMethods.Ftp.UploadFile;
            request.EnableSsl   = transportMode == "SFTP" ? true : false;

            using(FileStream sourceStream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
            {
                long fileLength = sourceStream.Length;

                using(Stream targetStream = request.GetRequestStream())
                {
                    byte[] bufferArray    = new byte[65536];
                    long   totalReadCount = 0L;

                    while(true)
                    {
                        int readCount = sourceStream.Read(bufferArray, 0, bufferArray.Length);

                        if(readCount == 0)
                        {
                            break;
                        }

                        totalReadCount += readCount;

                        targetStream.Write(bufferArray, 0, readCount);

                        reportAction?.Invoke(fileLength, totalReadCount);
                    }

                    reportAction?.Invoke(fileLength, totalReadCount);
                }
            }
        }

        #endregion
        #region 파일 다운로드 하기 - DownloadFile(transportMode, sourceURI, targetFilePath, userID, password, reportAction)

        /// <summary>
        /// 파일 다운로드 하기
        /// </summary>
        /// <param name="transportMode">전송 모드</param>
        /// <param name="sourceURI">소스 URI</param>
        /// <param name="targetFilePath">타겟 파일 경로</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        /// <param name="reportAction">리포트 액션</param>
        public static void DownloadFile(string transportMode, string sourceURI, string targetFilePath, string userID, string password, Action<long> reportAction = null)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sourceURI);

            request.Credentials = new NetworkCredential(userID, password);
            request.Method      = WebRequestMethods.Ftp.DownloadFile;
            request.EnableSsl   = transportMode == "SFTP" ? true : false;

            using(FtpWebResponse response = (FtpWebResponse)request.GetResponse())
            {
                Stream sourceStream = response.GetResponseStream();

                using(FileStream targetStream = new FileStream(targetFilePath, FileMode.Create, FileAccess.Write))
                {
                    byte[] bufferArray    = new byte[65536];
                    long   totalReadCount = 0L;

                    while(true)
                    {
                        int readCount = sourceStream.Read(bufferArray, 0, bufferArray.Length);

                        if(readCount == 0)
                        {
                            break;
                        }

                        totalReadCount += readCount;

                        targetStream.Write(bufferArray, 0, readCount);

                        reportAction?.Invoke(totalReadCount);
                    }

                    reportAction?.Invoke(totalReadCount);
                }
            }
        }

        #endregion
        #region 파일 삭제하기 - DeleteFile(transportMode, targetURI, userID, password)

        /// <summary>
        /// 파일 삭제하기
        /// </summary>
        /// <param name="transportMode">전송 모드</param>
        /// <param name="targetURI">타겟 URI</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        public static void DeleteFile(string transportMode, string targetURI, string userID, string password)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetURI);

            request.Credentials = new NetworkCredential(userID, password);
            request.Method      = WebRequestMethods.Ftp.DeleteFile;
            request.EnableSsl   = transportMode == "SFTP" ? true : false;

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        }

        #endregion

        #region 디렉토리 만들기 - MakeDirectory(serverAddress, directoryURI, userID, password)

        /// <summary>
        /// 디렉토리 만들기
        /// </summary>
        /// <param name="serverAddress">서버 주소</param>
        /// <param name="directoryURI">디렉토리 URI</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        public static void MakeDirectory(string serverAddress, string directoryURI, string userID, string password)
        {
            FtpWebRequest request = null;
            Stream        stream  = null;

            string[] pathArray = directoryURI.Split('/');

            string currentURI = serverAddress;

            foreach(string path in pathArray)
            {
                try
                {
                    currentURI = currentURI + "/" + path;

                    request = (FtpWebRequest)FtpWebRequest.Create(currentURI);

                    request.Method      = WebRequestMethods.Ftp.MakeDirectory;
                    request.UseBinary   = true;
                    request.Credentials = new NetworkCredential(userID, password);

                    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                    stream = response.GetResponseStream();

                    stream.Close();

                    response.Close();
                }
                catch(Exception)
                {
                }
            }
        }

        #endregion
        #region 디렉토리 삭제하기 - DeleteDirectory(transportMode, targetURI, userID, password)

        /// <summary>
        /// 디렉토리 삭제하기
        /// </summary>
        /// <param name="transportMode">전송 모드</param>
        /// <param name="targetURI">타겟 URI</param>
        /// <param name="userID">사용자 ID</param>
        /// <param name="password">패스워드</param>
        public static void DeleteDirectory(string transportMode, string targetURI, string userID, string password)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetURI);

            request.Credentials = new NetworkCredential(userID, password);
            request.Method      = WebRequestMethods.Ftp.RemoveDirectory;
            request.EnableSsl   = transportMode == "SFTP" ? true : false;

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        }

        #endregion
    }
}

 

300x250

 

▶ MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 연결 여부
        /// </summary>
        private bool isConnected = false;

        /// <summary>
        /// 운영 체제 타입
        /// </summary>
        private string osType = null;

        /// <summary>
        /// 전송 모드
        /// </summary>
        private string transportMode = null;

        /// <summary>
        /// 서버 주소
        /// </summary>
        private string serverAddress = null;

        /// <summary>
        /// 사용자 ID
        /// </summary>
        private string userID = null;

        /// <summary>
        /// 패스워드
        /// </summary>
        private string password = null;

        /// <summary>
        /// 현재 디렉토리 리스트
        /// </summary>
        private List<string> currentDirectoryList = new List<string>();

        /// <summary>
        /// 파일 열기 대화 상자
        /// </summary>
        private OpenFileDialog openFileDialog = null;

        /// <summary>
        /// 폴더 브라우저 대화 상자
        /// </summary>
        private FolderBrowserDialog folderBrowserDialog = null;

        /// <summary>
        /// 파일 업로드 작업자
        /// </summary>
        private BackgroundWorker uploadFileWorker = null;

        /// <summary>
        /// 파일 다운로드 작업자
        /// </summary>
        private BackgroundWorker downloadFileWorker = null;

        /// <summary>
        /// 디렉토리 다운로드 작업자
        /// </summary>
        private BackgroundWorker downloadDirectoryWorker = null;


        /// <summary>
        /// 디렉토리 삭제 작업자
        /// </summary>
        private BackgroundWorker deleteDirectoryWorker = null;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Consturctor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 파일 열기 대화 상자를 설정한다.

            this.openFileDialog = new OpenFileDialog();

            this.openFileDialog.CheckFileExists = true;
            this.openFileDialog.Multiselect     = false;
            this.openFileDialog.Title           = "업로드 파일 선택";
            this.openFileDialog.Filter          = "모든 파일(*.*)|*.*";
            this.openFileDialog.FilterIndex     = 1;

            #endregion
            #region 폴더 브라우저 대화 상자를 설정한다.

            this.folderBrowserDialog = new FolderBrowserDialog();

            this.folderBrowserDialog.ShowNewFolderButton = true;
            this.folderBrowserDialog.RootFolder          = Environment.SpecialFolder.MyComputer;

            #endregion
            #region 파일 업로드 작업자를 설정한다.

            this.uploadFileWorker = new BackgroundWorker();

            this.uploadFileWorker.WorkerReportsProgress = true;

            #endregion
            #region 파일 다운로드 작업자를 설정한다.

            this.downloadFileWorker = new BackgroundWorker();

            this.downloadFileWorker.WorkerReportsProgress = true;

            #endregion
            #region 디렉토리 삭제 작업자를 설정한다.

            this.deleteDirectoryWorker = new BackgroundWorker();

            this.deleteDirectoryWorker.WorkerReportsProgress = true;

            #endregion
            #region 디렉토리 다운로드 작업자를 설정한다.

            this.downloadDirectoryWorker = new BackgroundWorker();

            this.downloadDirectoryWorker.WorkerReportsProgress = true;

            #endregion
            #region 윈도우즈 라디오 버튼을 설정한다.

            this.windowsRadioButton.Checked = true;

            #endregion
            #region FTP 라디오 버튼을 설정한다.

            this.ftpRadioButton.Checked = true;

            #endregion
            #region 리스트 데이터 그리드 뷰를 설정한다.

            this.listDataGridView.ReadOnly            = true;
            this.listDataGridView.AutoGenerateColumns = false;
            this.listDataGridView.SelectionMode       = DataGridViewSelectionMode.FullRowSelect;

            #endregion

            SetControlEnabled();

            SetListDataGridViewData(null);

            #region 이벤트를 설정한다.

            this.uploadFileWorker.DoWork                    += uploadFileWorker_DoWork;
            this.uploadFileWorker.RunWorkerCompleted        += uploadFileWorker_RunWorkerCompleted;
            this.uploadFileWorker.ProgressChanged           += uploadFileWorker_ProgressChanged;

            this.downloadFileWorker.DoWork                  += downloadFileWorker_DoWork;
            this.downloadFileWorker.RunWorkerCompleted      += downloadFileWorker_RunWorkerCompleted;
            this.downloadFileWorker.ProgressChanged         += downloadFileWorker_ProgressChanged;

            this.downloadDirectoryWorker.DoWork             += downloadDirectoryWorker_DoWork;
            this.downloadDirectoryWorker.RunWorkerCompleted += downloadDirectoryWorker_RunWorkerCompleted;
            this.downloadDirectoryWorker.ProgressChanged    += downloadDirectoryWorker_ProgressChanged;

            this.deleteDirectoryWorker.DoWork               += deleteDirectoryWorker_DoWork;
            this.deleteDirectoryWorker.RunWorkerCompleted   += deleteDirectoryWorker_RunWorkerCompleted;
            this.deleteDirectoryWorker.ProgressChanged      += deleteDirectoryWorker_ProgressChanged;

            this.connectButton.Click                        += connectButton_Click;
            this.listDataGridView.CellFormatting            += listDataGridView_CellFormatting;
            this.listDataGridView.CellDoubleClick           += listDataGridView_CellDoubleClick;
            this.uploadFileButton.Click                     += uploadFileButton_Click;
            this.downloadFileButton.Click                   += downloadFileButton_Click;
            this.deleteFileButton.Click                     += deleteFileButton_Click;
            this.createDirectoryButton.Click                += createDirectoryButton_Click;
            this.downloadDirectoryButton.Click              += downloadDirectoryButton_Click;
            this.deleteDirectoryButton.Click                += deleteDirectoryButton_Click;

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 파일 업로드 작업자 작업시 처리하기 - uploadFileWorker_DoWork(sender, e)

        /// <summary>
        /// 파일 업로드 작업자 작업시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void uploadFileWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] parameterArray = (object[])e.Argument;

            string sourceFilePath = (string)parameterArray[0];
            string targetURI      = (string)parameterArray[1];

            Action<long, long> reportAction = delegate(long fileLength, long uploadLength)
            {
                int progress = (int)(((double)uploadLength / (double)fileLength) * 100d);

                this.uploadFileWorker.ReportProgress(progress);
            };

            try
            {
                FTPHelper.UploadFile(this.transportMode, sourceFilePath, targetURI, this.userID, this.password, reportAction);
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("파일 업로드시 에러가 발생했습니다.", exception);
            }
        }

        #endregion
        #region 파일 업로드 작업자 진행 상태 변경시 처리하기 - uploadFileWorker_ProgressChanged(sender, e)

        /// <summary>
        /// 파일 업로드 작업자 진행 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void uploadFileWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.uploadFileButton.Text = e.ProgressPercentage.ToString() + "%";

            this.uploadFileButton.Update();
        }

        #endregion
        #region 파일 업로드 작업자 작업 완료시 처리하기 - uploadFileWorker_RunWorkerCompleted(sender, e)

        /// <summary>
        /// 파일 업로드 작업자 작업 완료시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void uploadFileWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateListDataGridViewData();

            this.uploadFileButton.Text = "파일 업로드";

            Enabled = true;
        }

        #endregion

        #region 파일 다운로드 작업자 작업시 처리하기 - downloadFileWorker_DoWork(sender, e)

        /// <summary>
        /// 파일 다운로드 작업자 작업시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadFileWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] parameterArray = (object[])e.Argument;

            string sourceURI      = (string)parameterArray[0]; 
            string targetFilePath = (string)parameterArray[1];
            long   fileLength     = (long  )parameterArray[2];

            Action<long> reportAction = delegate(long downloadLength)
            {
                int progress = (int)(((double)downloadLength / (double)fileLength) * 100d);

                this.downloadFileWorker.ReportProgress(progress);
            };

            try
            {
                FTPHelper.DownloadFile(this.transportMode, sourceURI, targetFilePath, this.userID, this.password, reportAction);
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("파일 다운로드시 에러가 발생했습니다.", exception);
            }
        }

        #endregion
        #region 파일 다운로드 작업자 진행 상태 변경시 처리하기 - downloadFileWorker_ProgressChanged(sender, e)

        /// <summary>
        /// 파일 다운로드 작업자 진행 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadFileWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.downloadFileButton.Text = e.ProgressPercentage.ToString() + "%";

            this.downloadFileButton.Update();
        }

        #endregion
        #region 파일 다운로드 작업자 작업 완료시 처리하기 - downloadFileWorker_RunWorkerCompleted(sender, e)

        /// <summary>
        /// 파일 다운로드 작업자 작업 완료시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadFileWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.downloadFileButton.Text = "파일 다운로드";

            Enabled = true;
        }

        #endregion

        #region 디렉토리 다운로드 작업자 작업시 처리하기 - downloadDirectoryWorker_DoWork(sender, e)

        /// <summary>
        /// 디렉토리 다운로드 작업자 작업시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadDirectoryWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] parameterArray = (object[])e.Argument;

            FTPItem sourceItem = (FTPItem)parameterArray[0];

            string sourceRootDirectoryURI  = string.IsNullOrEmpty(sourceItem.DirectoryURI) ? sourceItem.ItemName : sourceItem.DirectoryURI + "/" + sourceItem.ItemName;
            string targetRootDirectoryPath = Path.Combine((string)parameterArray[1], sourceItem.ItemName);

            List<FTPItem> targetList = new List<FTPItem>();

            AddFileToList(targetList, sourceRootDirectoryURI);

            int sourceRootDirectoryURILength = sourceRootDirectoryURI.Length;

            for(int i = 0; i < targetList.Count; i++)
            {
                this.downloadDirectoryWorker.ReportProgress((int)(((double)i / (double)targetList.Count) * 100d));

                FTPItem targetItem = targetList[i];

                string subdirectoryURI;

                if(targetItem.DirectoryURI.Length == sourceRootDirectoryURILength)
                {
                    subdirectoryURI = string.Empty;
                }
                else
                {
                    subdirectoryURI = targetItem.DirectoryURI.Substring(sourceRootDirectoryURILength + 1);
                }

                string targetDirectoryPath = Path.Combine(targetRootDirectoryPath, subdirectoryURI.Replace("/", @"\"));
                string targetFilePath      = Path.Combine(targetDirectoryPath, targetItem.ItemName);
                string sourceURI           = string.IsNullOrEmpty(targetItem.DirectoryURI) ? this.serverAddress + "/" + targetItem.ItemName :
                                                 this.serverAddress + "/" + targetItem.DirectoryURI + "/" + targetItem.ItemName;

                if(!Directory.Exists(targetDirectoryPath))
                {
                    Directory.CreateDirectory(targetDirectoryPath);
                }

                try
                {
                    FTPHelper.DownloadFile(this.transportMode, sourceURI, targetFilePath, this.userID, this.password, null);
                }
                catch(Exception exception)
                {
                    ShowErrorMessageBox("디렉토리 다운로드시 에러가 발생했습니다.", exception);

                    break;
                }
            }

            this.downloadDirectoryWorker.ReportProgress(100);
        }

        #endregion
        #region 디렉토리 다운로드 작업자 진행 상태 변경시 처리하기 - downloadDirectoryWorker_ProgressChanged(sender, e)

        /// <summary>
        /// 디렉토리 다운로드 작업자 진행 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadDirectoryWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.downloadDirectoryButton.Text = e.ProgressPercentage.ToString() + "%";

            this.downloadDirectoryButton.Update();
        }

        #endregion
        #region 디렉토리 다운로드 작업자 작업 완료시 처리하기 - downloadDirectoryWorker_RunWorkerCompleted(sender, e)

        /// <summary>
        /// 디렉토리 다운로드 작업자 작업 완료시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadDirectoryWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.downloadDirectoryButton.Text = "디렉토리 다운로드";

            Enabled = true;
        }

        #endregion

        #region 디렉토리 삭제 작업자 작업시 처리하기 - deleteDirectoryWorker_DoWork(sender, e)

        /// <summary>
        /// 디렉토리 삭제 작업자 작업시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteDirectoryWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] parameterArray = (object[])e.Argument;

            FTPItem sourceItem = (FTPItem)parameterArray[0];

            string sourceRootDirectoryURI = string.IsNullOrEmpty(sourceItem.DirectoryURI) ? sourceItem.ItemName : sourceItem.DirectoryURI + "/" + sourceItem.ItemName;

            List<FTPItem> fileList      = new List<FTPItem>();
            List<FTPItem> directoryList = new List<FTPItem>();

            try
            {
                AddToList(fileList, directoryList, sourceRootDirectoryURI);
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("디렉토리 삭제 중 리스트 수집시 에러가 발생했습니다.", exception);

                return;
            }

            directoryList.Add(sourceItem);

            for(int i = 0; i < fileList.Count; i++)
            {
                FTPItem item = fileList[i];

                string targetURI = string.IsNullOrEmpty(item.DirectoryURI) ? this.serverAddress + "/" + item.ItemName :
                                       this.serverAddress + "/" + item.DirectoryURI + "/" + item.ItemName;

                try
                {
                    FTPHelper.DeleteFile(this.transportMode, targetURI, this.userID, this.password);
                }
                catch(Exception exception)
                {
                    ShowErrorMessageBox("디렉토리 삭제 중 파일 삭제시 에러가 발생했습니다.", exception);

                    return;
                }
            }

            this.deleteDirectoryWorker.ReportProgress(50);

            for(int i = 0; i < directoryList.Count; i++)
            {
                FTPItem item = directoryList[i];

                string targetURI = string.IsNullOrEmpty(item.DirectoryURI) ? this.serverAddress + "/" + item.ItemName :
                                       this.serverAddress + "/" + item.DirectoryURI + "/" + item.ItemName;

                try
                {
                    FTPHelper.DeleteDirectory(this.transportMode, targetURI, this.userID, this.password);
                }
                catch(Exception exception)
                {
                    ShowErrorMessageBox("디렉토리 삭제중 디렉토리 삭제시 에러가 발생했습니다.", exception);

                    return;
                }
            }

            this.deleteDirectoryWorker.ReportProgress(100);
        }

        #endregion
        #region 디렉토리 삭제 작업자 진행 상태 변경시 처리하기 - deleteDirectoryWorker_ProgressChanged(sender, e)

        /// <summary>
        /// 디렉토리 삭제 작업자 진행 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteDirectoryWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.deleteDirectoryButton.Text = e.ProgressPercentage.ToString() + "%";

            this.deleteDirectoryButton.Update();
        }

        #endregion
        #region 디렉토리 삭제 작업자 작업 완료시 처리하기 - deleteDirectoryWorker_RunWorkerCompleted(sender, e)

        /// <summary>
        /// 디렉토리 삭제 작업자 작업 완료시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteDirectoryWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.deleteDirectoryButton.Text = "디렉토리 삭제";

            UpdateListDataGridViewData();

            Enabled = true;
        }

        #endregion

        #region 접속하기 버튼 클릭시 처리하기 - connectButton_Click(sender, e)

        /// <summary>
        /// 접속하기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void connectButton_Click(object sender, EventArgs e)
        {
            if(this.isConnected)
            {
                this.currentDirectoryList.Clear();

                SetListDataGridViewData(null);

                SetCurrentDirectoryTextBoxData();

                this.isConnected = false;

                SetControlEnabled();
            }
            else
            {
                #region 운영 체제 타입을 구한다.

                this.osType = this.windowsRadioButton.Checked ? "WINDOWS" : "UNIX";

                #endregion
                #region 전송 모드를 구한다.

                this.transportMode = this.ftpRadioButton.Checked ? "FTP" : "SFTP";

                #endregion
                #region 서버 주소를 구한다.

                this.serverAddress = this.serverAddressTextBox.Text.Trim();

                if(string.IsNullOrWhiteSpace(this.serverAddress))
                {
                    ShowInformationMessageBox("서버 주소를 입력해 주시기 바랍니다.");

                    return;
                }

                #endregion
                #region 사용자 ID를 구한다.

                this.userID = this.userIDTextBox.Text.Trim();

                if(string.IsNullOrWhiteSpace(this.userID))
                {
                    ShowInformationMessageBox("사용자 ID를 입력해 주시기 바랍니다.");

                    return;
                }

                #endregion
                #region 패스워드를 구한다.

                this.password = this.passwordTextBox.Text.Trim();

                if(string.IsNullOrWhiteSpace(this.password))
                {
                    ShowInformationMessageBox("패스워드를 입력해 주시기 바랍니다.");

                    return;
                }

                #endregion

                this.currentDirectoryList.Clear();

                if(UpdateListDataGridViewData())
                {
                    SetCurrentDirectoryTextBoxData();

                    this.isConnected = true;

                    SetControlEnabled();
                }
            }
        }

        #endregion

        #region 리스트 데이터 그리드 뷰 셀 포매팅 처리하기 - listDataGridView_CellFormatting(sender, e)

        /// <summary>
        /// 리스트 데이터 그리드 뷰 셀 포매팅 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void listDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            DataGridView dataGridView = sender as DataGridView;

            if(dataGridView.Columns[e.ColumnIndex].DataPropertyName == "ItemType")
            {
                if(e.Value != null)
                {
                    string itemType = e.Value.ToString();

                    Color foregroundColor = (itemType == "DIRECTORY") ? Color.Red : Color.Black;

                    for(int i = 0; i < dataGridView.Rows[e.RowIndex].Cells.Count; i++)
                    {
                        dataGridView.Rows[e.RowIndex].Cells[i].Style.ForeColor = foregroundColor;
                    }
                }
            }
        }

        #endregion
        #region 리스트 데이터 그리드 뷰 셀 더블 클릭시 처리하기 - listDataGridView_CellDoubleClick(sender, e)

        /// <summary>
        /// 리스트 데이터 그리드 뷰 셀 더블 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void listDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dataGridView = sender as DataGridView;

            FTPItem item = dataGridView.Rows[e.RowIndex].DataBoundItem as FTPItem;

            if(item != null)
            {
                if(item.ItemType == "DIRECTORY")
                {
                    if(!string.IsNullOrEmpty(item.ItemName))
                    {
                        if(item.ItemName == "..")
                        {
                            this.currentDirectoryList.Remove(this.currentDirectoryList[this.currentDirectoryList.Count - 1]);
                        }
                        else
                        {
                            this.currentDirectoryList.Add(item.ItemName);
                        }

                        UpdateListDataGridViewData();

                        SetCurrentDirectoryTextBoxData();
                    }
                }
            }
        }

        #endregion

        #region 파일 업로드 버튼 클릭시 처리하기 - uploadFileButton_Click(sender, e)

        /// <summary>
        /// 파일 업로드 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void uploadFileButton_Click(object sender, EventArgs e)
        {
            #region 소스 파일 경로를 구한다.

            DialogResult result = this.openFileDialog.ShowDialog(this);

            if(result != DialogResult.OK)
            {
                return;
            }

            string sourceFilePath = this.openFileDialog.FileName;

            #endregion

            string sourceFileName     = Path.GetFileName(sourceFilePath);
            string targerDirectoryURI = GetCurrentDirectoryURI();
            string targetURI          = string.IsNullOrEmpty(targerDirectoryURI) ? this.serverAddress + "/" + sourceFileName :
                                            this.serverAddress + "/" + targerDirectoryURI + "/" + sourceFileName;

            #region 파일 업로드 여부를 확인한다.

            string message = string.Format("선택한 파일을 업로드 하시겠습니까?\n{0}\n{1}", sourceFilePath, targetURI);

            if(ShowQuestionMessageBox(message) != DialogResult.Yes)
            {
                return;
            }

            #endregion

            Enabled = false;

            this.uploadFileWorker.RunWorkerAsync(new object[] { sourceFilePath, targetURI });
        }

        #endregion
        #region 파일 다운로드 버튼 클릭시 처리하기 - downloadFileButton_Click(sender, e)

        /// <summary>
        /// 파일 다운로드 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadFileButton_Click(object sender, EventArgs e)
        {
            #region 타겟 항목을 구한다.

            DataGridViewSelectedRowCollection sourceCollection = this.listDataGridView.SelectedRows;

            if(sourceCollection == null || sourceCollection.Count == 0)
            {
                ShowInformationMessageBox("목록에서 선택한 항목이 없습니다.");

                return;
            }

            FTPItem targetItem = null;

            for(int i = 0; i < sourceCollection.Count; i++)
            {
                DataGridViewRow sourceRow = sourceCollection[i];

                FTPItem sourceItem = sourceRow.DataBoundItem as FTPItem;

                if(sourceItem.ItemType == "FILE")
                {
                    targetItem = sourceItem;

                    break;
                }
            }

            if(targetItem == null)
            {
                ShowInformationMessageBox("선택한 파일이 없습니다.");

                return;
            }

            #endregion
            #region 타겟 디렉토리 경로를 선택한다.

            if(this.folderBrowserDialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            string targetDirectoryPath = this.folderBrowserDialog.SelectedPath;

            #endregion

            string targetFileName      = targetItem.ItemName;
            string targetFilePath      = Path.Combine(targetDirectoryPath, targetFileName);
            string sourceDirectoryURI  = GetCurrentDirectoryURI();
            string sourceURI           = string.IsNullOrEmpty(sourceDirectoryURI) ? this.serverAddress + "/" + targetFileName :
                                             this.serverAddress + "/" + sourceDirectoryURI + "/" + targetFileName;

            #region 파일 다운로드 여부를 확인한다.

            string dialogMessage = string.Format("선택한 파일을 다운로드 하시겠습니까?\n{0}", sourceURI);

            if(ShowQuestionMessageBox(dialogMessage) != DialogResult.Yes)
            {
                return;
            }

            #endregion

            Enabled = false;

            this.downloadFileWorker.RunWorkerAsync(new object[] { sourceURI, targetFilePath, targetItem.FileLength });
        }

        #endregion
        #region 파일 삭제 버튼 클릭시 처리하기 - deleteButton_Click(sender, e)

        /// <summary>
        /// 파일 삭제 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteFileButton_Click(object sender, EventArgs e)
        {
            #region 타겟 항목을 구한다.

            DataGridViewSelectedRowCollection sourceCollection = this.listDataGridView.SelectedRows;

            if(sourceCollection == null || sourceCollection.Count == 0)
            {
                ShowInformationMessageBox("목록에서 선택한 항목이 없습니다.");

                return;
            }

            FTPItem targetItem = null;

            for(int i = 0; i < sourceCollection.Count; i++)
            {
                DataGridViewRow sourceRow = sourceCollection[i];

                FTPItem sourceItem = sourceRow.DataBoundItem as FTPItem;

                if(sourceItem.ItemType == "FILE")
                {
                    targetItem = sourceItem;

                    break;
                }
            }

            if(targetItem == null)
            {
                ShowInformationMessageBox("선택한 파일이 없습니다.");

                return;
            }

            #endregion

            string targetDirectoryURI = GetCurrentDirectoryURI();
            string targetFileName     = targetItem.ItemName;
            string targetURI          = string.IsNullOrEmpty(targetDirectoryURI) ? this.serverAddress + "/" + targetFileName :
                                            this.serverAddress + "/" + targetDirectoryURI + "/" + targetFileName;

            #region 파일 삭제 여부를 확인한다.

            string message = string.Format("선택한 파일을 삭제하시겠습니까?\n{0}", targetURI);

            if(ShowQuestionMessageBox(message) != DialogResult.Yes)
            {
                return;
            }

            #endregion

            try
            {
                FTPHelper.DeleteFile(this.transportMode, targetURI, this.userID, this.password);
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("파일 삭제시 에러가 발생했습니다.", exception);

                return;
            }

            UpdateListDataGridViewData();
        }

        #endregion
        #region 디렉토리 생성 버튼 클릭시 처리하기 - createDirectoryButton_Click(sender, e)

        /// <summary>
        /// 디렉토리 생성 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void createDirectoryButton_Click(object sender, EventArgs e)
        {
            #region 디렉토리명을 구한다.

            InputDirectoryNameForm form = new InputDirectoryNameForm();

            form.StartPosition = FormStartPosition.CenterParent;

            if(form.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            string directoryName = form.DirectoryName;

            #endregion

            string currentDirectoryURI = GetCurrentDirectoryURI();
            string directoryURI        = string.IsNullOrEmpty(currentDirectoryURI) ? directoryName : currentDirectoryURI + "/" + directoryName;

            try
            {
                FTPHelper.MakeDirectory(this.serverAddress, directoryURI, this.userID, this.password);
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("디렉토리 생성시 에러가 발생했습니다.", exception);

                return;
            }

            UpdateListDataGridViewData();
        }

        #endregion
        #region 디렉토리 다운로드 버튼 클릭시 처리하기 - downloadDirectoryButton_Click(sender, e)

        /// <summary>
        /// 디렉토리 다운로드 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void downloadDirectoryButton_Click(object sender, EventArgs e)
        {
            #region 타겟 항목을 구한다.

            DataGridViewSelectedRowCollection sourceCollection = this.listDataGridView.SelectedRows;

            if(sourceCollection == null || sourceCollection.Count == 0)
            {
                ShowInformationMessageBox("목록에서 선택한 항목이 없습니다.");

                return;
            }

            FTPItem targetItem = null;

            for(int i = 0; i < sourceCollection.Count; i++)
            {
                DataGridViewRow sourceRow = sourceCollection[i];

                FTPItem sourceItem = sourceRow.DataBoundItem as FTPItem;

                if(sourceItem.ItemType == "DIRECTORY")
                {
                    targetItem = sourceItem;

                    break;
                }
            }

            if(targetItem == null)
            {
                ShowInformationMessageBox("선택한 디렉토리가 없습니다.");

                return;
            }

            #endregion
            #region 타겟 디렉토리 경로를 구한다.

            if(this.folderBrowserDialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            string targetDirectoryPath = this.folderBrowserDialog.SelectedPath;

            #endregion

            Enabled = false;

            this.downloadDirectoryWorker.RunWorkerAsync(new object[] { targetItem, targetDirectoryPath });
        }

        #endregion
        #region 디렉토리 삭제 버튼 클릭시 처리하기 - deleteDirectoryButton_Click(sender, e)

        /// <summary>
        /// 디렉토리 삭제 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteDirectoryButton_Click(object sender, EventArgs e)
        {
            #region 타겟 항목을 구합니다.

            DataGridViewSelectedRowCollection sourceCollection = this.listDataGridView.SelectedRows;

            if(sourceCollection == null || sourceCollection.Count == 0)
            {
                ShowInformationMessageBox("목록에서 선택한 항목이 없습니다.");

                return;
            }

            FTPItem targetItem = null;

            for(int i = 0; i < sourceCollection.Count; i++)
            {
                DataGridViewRow sourceRow = sourceCollection[i];

                FTPItem sourceItem = sourceRow.DataBoundItem as FTPItem;

                if(sourceItem.ItemType == "DIRECTORY")
                {
                    targetItem = sourceItem;

                    break;
                }
            }

            if(targetItem == null)
            {
                ShowInformationMessageBox("선택한 디렉토리가 없습니다.");

                return;
            }

            #endregion

            string targetURI = string.IsNullOrEmpty(targetItem.DirectoryURI) ? this.serverAddress + "/" + targetItem.ItemName :
                                   this.serverAddress + "/" + targetItem.DirectoryURI + "/" + targetItem.ItemName;

            #region 디렉토리 삭제 여부를 확인한다.

            string message = string.Format("선택한 디렉토리를 삭제하시겠습니까?\n{0}", targetURI);

            if(ShowQuestionMessageBox(message) != DialogResult.Yes)
            {
                return;
            }

            #endregion

            Enabled = false;

            this.deleteDirectoryWorker.RunWorkerAsync(new object[] { targetItem });
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 정보 메시지 박스 표시하기 - ShowInformationMessageBox(message)

        /// <summary>
        /// 정보 메시지 박스 표시하기
        /// </summary>
        /// <param name="message">메시지</param>
        private void ShowInformationMessageBox(string message)
        {
            MessageBox.Show(this, message, "INFORMATION", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        #endregion
        #region 질문 메시지 박스 표시하기 - ShowQuestionMessageBox(message)

        /// <summary>
        /// 질문 메시지 박스 표시하기
        /// </summary>
        /// <param name="message">메시지</param>
        /// <returns>대화 상자 결과</returns>
        private DialogResult ShowQuestionMessageBox(string message)
        {
            DialogResult result = MessageBox.Show(this, message, "CONFIRMATION", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            return result;
        }

        #endregion
        #region 에러 메시지 박스 표시하기 - ShowErrorMessageBox(message, exception)

        /// <summary>
        /// 에러 메시지 박스 표시하기
        /// </summary>
        /// <param name="message">메시지</param>
        /// <param name="exception">예외</param>
        private void ShowErrorMessageBox(string message, Exception exception)
        {
            MessageBox.Show(this, message + "\n" + exception.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        #endregion

        #region 현재 디렉토리 URI 구하기 - GetCurrentDirectoryURI()

        /// <summary>
        /// 현재 디렉토리 URI 구하기
        /// </summary>
        /// <returns>현재 디렉토리 URI</returns>
        private string GetCurrentDirectoryURI()
        {
            if(this.currentDirectoryList.Count == 0)
            {
                return string.Empty;
            }

            StringBuilder stringBuilder = new StringBuilder();

            foreach(string item in this.currentDirectoryList)
            {
                if(stringBuilder.Length > 0)
                {
                    stringBuilder.Append("/");
                }

                stringBuilder.Append(item);
            }

            return stringBuilder.ToString();
        }

        #endregion
        #region 리스트 구하기 - GetList(directoryURI)

        /// <summary>
        /// 리스트 구하기
        /// </summary>
        /// <param name="directoryURI">디렉토리 URI</param>
        /// <returns></returns>
        private List<FTPItem> GetList(string directoryURI)
        {
            List<FTPItem> list = FTPHelper.GetList(this.osType, this.transportMode, this.serverAddress, directoryURI, this.userID, this.password);

            return list;
        }

        #endregion
        #region 리스트에 파일 추가하기 - AddFileToList(fileList, rootDirectoryURI)

        /// <summary>
        /// 리스트에 파일 추가하기
        /// </summary>
        /// <param name="fileList">파일 리스트</param>
        /// <param name="rootDirectoryURI">루트 디렉토리 URI</param>
        private void AddFileToList(List<FTPItem> fileList, string rootDirectoryURI)
        {
            List<FTPItem> childList = GetList(rootDirectoryURI);

            foreach(FTPItem childItem in childList)
            {
                if(childItem.ItemType == "FILE")
                {
                    fileList.Add(childItem);
                }
                else if(childItem.ItemType == "DIRECTORY")
                {
                    AddFileToList(fileList, rootDirectoryURI + "/" + childItem.ItemName);
                }
            }
        }

        #endregion
        #region 리스트에 파일 추가하기 - AddToList(fileList, directoryList, rootDirectoryURI)

        /// <summary>
        /// 리스트에 파일 추가하기
        /// </summary>
        /// <param name="fileList">파일 리스트</param>
        /// <param name="directoryList">디렉토리 리스트</param>
        /// <param name="rootDirectoryURI">루트 디렉토리 URI</param>
        private void AddToList(List<FTPItem> fileList, List<FTPItem> directoryList, string rootDirectoryURI)
        {
            List<FTPItem> childList = GetList(rootDirectoryURI);

            foreach(FTPItem childItem in childList)
            {
                if(childItem.ItemType == "FILE")
                {
                    fileList.Insert(0, childItem);
                }
                else if(childItem.ItemType == "DIRECTORY")
                {
                    directoryList.Insert(0, childItem);

                    AddToList(fileList, directoryList, rootDirectoryURI + "/" + childItem.ItemName);
                }
            }
        }

        #endregion

        #region 컨트롤 활성화 여부 설정하기 - SetControlEnabled()

        /// <summary>
        /// 컨트롤 활성화 여부 설정하기
        /// </summary>
        private void SetControlEnabled()
        {
            if(this.isConnected)
            {
                this.osGroupBox.Enabled              = false;
                this.transportModeGroupBox.Enabled   = false;

                this.serverAddressTextBox.ReadOnly   = true;
                this.userIDTextBox.ReadOnly          = true;
                this.passwordTextBox.ReadOnly        = true;

                this.connectButton.Text = "접속끊기";

                this.uploadFileButton.Enabled        = true;
                this.downloadFileButton.Enabled      = true;
                this.deleteFileButton.Enabled        = true;
                this.createDirectoryButton.Enabled   = true;
                this.downloadDirectoryButton.Enabled = true;
                this.deleteDirectoryButton.Enabled   = true;
            }
            else
            {
                this.osGroupBox.Enabled              = true;
                this.transportModeGroupBox.Enabled   = true;

                this.serverAddressTextBox.ReadOnly   = false;
                this.userIDTextBox.ReadOnly          = false;
                this.passwordTextBox.ReadOnly        = false;

                this.connectButton.Text = "접속하기";

                this.uploadFileButton.Enabled        = false;
                this.downloadFileButton.Enabled      = false;
                this.downloadDirectoryButton.Enabled = false;
                this.createDirectoryButton.Enabled   = false;
                this.deleteFileButton.Enabled        = false;
                this.deleteDirectoryButton.Enabled   = false;
            }
        }

        #endregion

        #region 현재 디렉토리 텍스트 박스 데이터 설정하기 - SetCurrentDirectoryTextBoxData()

        /// <summary>
        /// 현재 디렉토리 텍스트 박스 데이터 설정하기
        /// </summary>
        private void SetCurrentDirectoryTextBoxData()
        {
            string uri = GetCurrentDirectoryURI();

            if(string.IsNullOrEmpty(uri))
            {
                this.currentDirectoryTextBox.Text = "/";
            }
            else
            {
                this.currentDirectoryTextBox.Text = "/" + uri;
            }
        }

        #endregion
        #region 데이터 그리드 뷰 셀 스타일 구하기 - GetDataGridViewCellStyle(backgroundColor, alignment)

        /// <summary>
        /// 데이터 그리드 뷰 셀 스타일 구하기
        /// </summary>
        /// <param name="backgroundColor">배경색</param>
        /// <param name="alignment">정렬</param>
        /// <returns>데이터 그리드 뷰 셀 스타일</returns>
        private DataGridViewCellStyle GetDataGridViewCellStyle(Color backgroundColor, DataGridViewContentAlignment alignment)
        {
            DataGridViewCellStyle style = new DataGridViewCellStyle();

            style.Alignment = alignment;
            style.BackColor = backgroundColor;

            return style;
        }

        #endregion
        #region 리스트 데이터 그리드 뷰 데이터 설정하기 - SetListDataGridViewData(dataSource)

        /// <summary>
        /// 리스트 데이터 그리드 뷰 데이터 설정하기
        /// </summary>
        /// <param name="dataSource">데이터 소스</param>
        private void SetListDataGridViewData(object dataSource)
        {
            if(this.listDataGridView.DataSource != null)
            {
                IDisposable disposable = this.listDataGridView.DataSource as IDisposable;

                this.listDataGridView.DataSource = null;

                if(disposable != null)
                {
                    disposable.Dispose();

                    disposable = null;
                }
            }

            #region 리스트 데이터 그리드 뷰 컬럼을 설정한다.

            this.listDataGridView.Columns.Clear();

            DataGridViewColumn column;

            column = new DataGridViewTextBoxColumn();

            column.Width                      = 90;
            column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            column.HeaderText                 = "생성일자";
            column.SortMode                   = DataGridViewColumnSortMode.NotSortable;
            column.DataPropertyName           = "CreateDateString";
            column.ValueType                  = typeof(string);
            column.DefaultCellStyle           = GetDataGridViewCellStyle(Color.White, DataGridViewContentAlignment.MiddleCenter);

            this.listDataGridView.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();

            column.Width                      = 90;
            column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            column.HeaderText                 = "생성시간";
            column.SortMode                   = DataGridViewColumnSortMode.NotSortable;
            column.DataPropertyName           = "CreateTimeString";
            column.ValueType                  = typeof(string);
            column.DefaultCellStyle           = GetDataGridViewCellStyle(Color.White, DataGridViewContentAlignment.MiddleCenter);

            this.listDataGridView.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();

            column.Width                      = 90;
            column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            column.HeaderText                 = "항목구분";
            column.SortMode                   = DataGridViewColumnSortMode.NotSortable;
            column.DataPropertyName           = "ItemType";
            column.ValueType                  = typeof(string);
            column.DefaultCellStyle           = GetDataGridViewCellStyle(Color.White, DataGridViewContentAlignment.MiddleLeft);

            this.listDataGridView.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();

            column.Width                      = 400;
            column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            column.HeaderText                 = "항목명";
            column.SortMode                   = DataGridViewColumnSortMode.NotSortable;
            column.DataPropertyName           = "ItemName";
            column.ValueType                  = typeof(string);
            column.DefaultCellStyle           = GetDataGridViewCellStyle(Color.White, DataGridViewContentAlignment.MiddleLeft);

            this.listDataGridView.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();

            column.Width                      = 120;
            column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            column.HeaderText                 = "파일길이";
            column.SortMode                   = DataGridViewColumnSortMode.NotSortable;
            column.DataPropertyName           = "FileLengthString";
            column.ValueType                  = typeof(string);
            column.DefaultCellStyle           = GetDataGridViewCellStyle(Color.White, DataGridViewContentAlignment.MiddleRight);

            this.listDataGridView.Columns.Add(column);

            #endregion

            this.listDataGridView.DataSource = dataSource;
        }

        #endregion
        #region 리스트 데이터 그리드 뷰 데이터 업데이트 하기 - UpdateListDataGridViewData()

        /// <summary>
        /// 리스트 데이터 그리드 뷰 데이터 업데이트 하기
        /// </summary>
        /// <remarks>처리 결과</remarks>
        private bool UpdateListDataGridViewData()
        {
            try
            {
                string sourceDirectoryURI = GetCurrentDirectoryURI();

                List<FTPItem> sourceList = GetList(sourceDirectoryURI);

                if(this.currentDirectoryList.Count > 0)
                {
                    sourceList.Insert
                    (
                        0,
                        new FTPItem
                        {
                            DirectoryURI     = sourceDirectoryURI,
                            CreateDateString = string.Empty      ,
                            CreateTimeString = string.Empty      ,
                            ItemType         = "DIRECTORY"       ,
                            FileLength       = 0                 ,
                            FileLengthString = string.Empty      ,
                            ItemName         = ".."
                        }
                    );
                }

                SetListDataGridViewData(sourceList);

                return true;
            }
            catch(Exception exception)
            {
                ShowErrorMessageBox("목록 조회시 에러가 발생했습니다.", exception);

                return false;
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요