공학속으로/C#

C# 텍스트 파일 라인수로 분할하여 저장하기

더월드 2023. 3. 6.

C# 에서 텍스트 파일을 열어서 라인수로 파일을 분할하는 프로그램을 만들어 보겠습니다.

 

1. 새프로젝트 만들기를 한후, Windows Forms 앱(Net Framework)을 선택하세요

 

2. 새프로젝트 구성에서 프로젝트 이름과 위치를 설정하고 만들기 버튼을 누르면 기본 윈도우가 생성됩니다.

 

3. 윈도우 폼을 우선 아래와 같이 만들어 줍니다.

1). TextBox : filesplit_textBox

2). numericUpDown: numericUpDown1

3). Button: fileselect_button

4). Button: splite_button

5). richTextBox : filesplite_richTextBox

6). Label: progress_label

7). progressBar: progressBar1

 

4. 파일 선택 다이얼로그 만들기

우선적으로 버튼을 더블 클릭해서, 버튼 클릭시 실행하는 함수를 만듭니다.

이 함수에서는 파일을 선택하는 다이얼로그을 이용하여 .csv나 .txt 형태의 파일을 열수 있도록 설정합니다.

        // 분할할 파일 선택 버튼
        private void fileselect_button_Click(object sender, EventArgs e)
        {
            var fileContent = string.Empty;
            var filePath = string.Empty;

            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "텍스트 파일 (*.csv, *.txt, *.parsed) | *.csv; *.txt; *.parsed; | 모든 파일 (*.*) | *.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    //Get the path of specified file
                    filePath = openFileDialog.FileName;

                    filesplit_textBox.Text = String.Format("{0}", filePath);
                    Log_print(filePath);
                }
            }

        }

 

5. 파일 분할하기

 파일을 분할하는 방법은 파일을 라인별로 파일을 읽고 저장하고, 파일의 라인수가 분할 라인수가 되면 새로운 파일을 생성하여 저장한다는 기본 개념을 가지고 있으면 쉽게 구현가능합니다.

 

1). 파일 분할 라인수를 받아오는데, string 을 int 로 바꾸는 Decimal.ToInt32 함수를 사용합니다.

 int splite_num = Decimal.ToInt32(numericUpDown1.Value);

 

2). 프로그레스바 최대값 설정
여기서는 파일의 전체라인수/분할 라인수를 해서 프로그레스바 최대값을 구합니다.
progressBar1.Maximum = (int)File.ReadAllLines(filesplit_textBox.Text).Length / splite_num;


3). 분할하여 저장할 파일 경로를 설정합니다.

여기서 분할할 파일 위치에 "\\out" 폴더를 생성하고,
 string output_path = Path.GetDirectoryName(inputfilename) + "\\out";
 if (Directory.Exists(output_path) == false)
{
    Directory.CreateDirectory(output_path);
}

분할 파일명은 뒤에 카우트.txt로 생성합니다.
string output_filename = output_path + "\\"+ string.Format("{0}", file_cnt) + ".txt";

4). 파일을 라인별로 읽습니다.
while ((line = inputFile.ReadLine()) != null)
{

 

}


5). 파일의 라인수가 분할 라인수가 되면 새로운 파일을 생성하여 저장합니다.
if(line_cnt == splite_num)
{
    file_cnt++;
    line_cnt = 0;

    outputFile.Close();
    output_filename = output_path + "\\" + string.Format("{0}", file_cnt) + ".txt";
    outputFile = new StreamWriter(output_filename);

    6). 새로운 파일이 생성되면 진행도를 올려줍니다.
    progressBar1.Value = progressBar1.Value + 1;
    progress_label.Text = (progressBar1.Value * 100 / progressBar1.Maximum).ToString() + " %";
    Application.DoEvents();
}     

        // 파일 분리 - 파일 분할 버튼
        private void splite_button_Click(object sender, EventArgs e)
        {
            // 분할할 파일이 선택되지 않았다면..
            if (String.IsNullOrEmpty(filesplit_textBox.Text))
            {
                Log_print("분할할 파일이 선택되지 않았습니다!!");

            }
            // 분할할 파일이 선택되었다면
            else
            {
                // 진행도 초기화
                progressBar1.Value = 0;
                progress_label.Text = "0 %";
                Application.DoEvents();

                // 파일 분할하기
                SpliteFile(filesplit_textBox.Text);
            }
        }

        // 텍스트 파일 분할하기
        public bool SpliteFile(string inputfilename)
        {
            bool Output = false;
            int file_cnt = 0;
            int line_cnt = 0;

            int splite_num = Decimal.ToInt32(numericUpDown1.Value);
            
            try
            {
                //최대값을 설정한다. 가령 progressBar1의 값이 10 인 경우 1프로에 해당한다.
                //여기서는 파일의 전체라인수/분할 라인수를 해서 프로그레스바 최대값을 구한다.
                progressBar1.Maximum = (int)File.ReadAllLines(filesplit_textBox.Text).Length / splite_num;
            }
            catch
            {
                //위 프로그레스바 최대값이 오류일때 100으로 한다.
                progressBar1.Maximum = 100;
            }
            
            try
            {
                file_cnt = 1;
                
                //분할하여 저장할 파일 경로를 설정한다.
                string output_path = Path.GetDirectoryName(inputfilename) + "\\out";
                if (Directory.Exists(output_path) == false)
                {
                    Directory.CreateDirectory(output_path);
                }

                //분할 파일명은 뒤에 카우트.txt로 생성한다.
                string output_filename = output_path + "\\"+ string.Format("{0}", file_cnt) + ".txt";

                // 입력, 출력 파일을 연다.
                var inputFile = new StreamReader(inputfilename);
                var outputFile = new StreamWriter(output_filename);

                string line;
                //라인별로 파일을 연다.
                while ((line = inputFile.ReadLine()) != null)
                {
                    //파일의 라인수가 분할 라인수가 되면 새로운 파일을 생성하여 저장한다.
                    if(line_cnt == splite_num)
                    {
                        file_cnt++;
                        line_cnt = 0;

                        outputFile.Close();
                        output_filename = output_path + "\\" + string.Format("{0}", file_cnt) + ".txt";
                        outputFile = new StreamWriter(output_filename);


                        // 새로운 파일이 생성되면 진행도를 올린다.
                        progressBar1.Value = progressBar1.Value + 1;
                        progress_label.Text = (progressBar1.Value * 100 / progressBar1.Maximum).ToString() + " %";
                        Application.DoEvents();
                    }                   

                    // 읽은 파일을 저장한다.
                    outputFile.WriteLine(line);
                    line_cnt++;
                }
                // 파일을 닫는다.
                //outPutFile.WriteLine();
                inputFile.Close();
                outputFile.Close();

                // 작업 종료 로그를 찍는다.
                Log_print("파일 나누기 완료!!");                
            }
            catch
            {
                Log_print("[Error] 파일 나누기에 실패하였습니다!!");
            }
            return Output;
        }
        
        //--------------------------
        // 로그 -richTextBox
        //--------------------------
        private void Log_print(string str_msg)
        {
            filesplite_richTextBox.AppendText(str_msg + Environment.NewLine);
            filesplite_richTextBox.ScrollToCaret();
        }

 

6. 프로그레스바 사용하기

6-1). 프로그레스바 최대값 설정
여기서는 파일의 전체라인수/분할 라인수를 해서 프로그레스바 최대값을 구한다.
progressBar1.Maximum = (int)File.ReadAllLines(filesplit_textBox.Text).Length / splite_num;

 

6-2). 새로운 파일이 생성되면 진행도를 올린다.

 // 진행도를 1올린다.

progressBar1.Value = progressBar1.Value + 1;

// 전체 진행도를 100으로 맞추고, 퍼센트로 표시한다.
progress_label.Text = (progressBar1.Value * 100 / progressBar1.Maximum).ToString() + " %";

// label 값 변화를 즉시 적용한다.

Application.DoEvents(); 

 

7. 전체 코드는 아래와 같다.

        // 분할할 파일 선택 버튼
        private void fileselect_button_Click(object sender, EventArgs e)
        {
            var fileContent = string.Empty;
            var filePath = string.Empty;

            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "텍스트 파일 (*.csv, *.txt, *.parsed) | *.csv; *.txt; *.parsed; | 모든 파일 (*.*) | *.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    //Get the path of specified file
                    filePath = openFileDialog.FileName;

                    filesplit_textBox.Text = String.Format("{0}", filePath);
                    Log_print(filePath);
                }
            }

        }
        
                // 파일 분리 - 파일 분할 버튼
        private void splite_button_Click(object sender, EventArgs e)
        {
            // 분할할 파일이 선택되지 않았다면..
            if (String.IsNullOrEmpty(filesplit_textBox.Text))
            {
                Log_print("분할할 파일이 선택되지 않았습니다!!");

            }
            // 분할할 파일이 선택되었다면
            else
            {
                // 진행도 초기화
                progressBar1.Value = 0;
                progress_label.Text = "0 %";
                Application.DoEvents();

                // 파일 분할하기
                SpliteFile(filesplit_textBox.Text);
            }
        }

        // 텍스트 파일 분할하기
        public bool SpliteFile(string inputfilename)
        {
            bool Output = false;
            int file_cnt = 0;
            int line_cnt = 0;

            int splite_num = Decimal.ToInt32(numericUpDown1.Value);
            
            try
            {
                //최대값을 설정한다. 가령 progressBar1의 값이 10 인 경우 1프로에 해당한다.
                //여기서는 파일의 전체라인수/분할 라인수를 해서 프로그레스바 최대값을 구한다.
                progressBar1.Maximum = (int)File.ReadAllLines(filesplit_textBox.Text).Length / splite_num;
            }
            catch
            {
                //위 프로그레스바 최대값이 오류일때 100으로 한다.
                progressBar1.Maximum = 100;
            }
            
            try
            {
                file_cnt = 1;
                
                //분할하여 저장할 파일 경로를 설정한다.
                string output_path = Path.GetDirectoryName(inputfilename) + "\\out";
                if (Directory.Exists(output_path) == false)
                {
                    Directory.CreateDirectory(output_path);
                }

                //분할 파일명은 뒤에 카우트.txt로 생성한다.
                string output_filename = output_path + "\\"+ string.Format("{0}", file_cnt) + ".txt";

                // 입력, 출력 파일을 연다.
                var inputFile = new StreamReader(inputfilename);
                var outputFile = new StreamWriter(output_filename);

                string line;
                //라인별로 파일을 연다.
                while ((line = inputFile.ReadLine()) != null)
                {
                    //파일의 라인수가 분할 라인수가 되면 새로운 파일을 생성하여 저장한다.
                    if(line_cnt == splite_num)
                    {
                        file_cnt++;
                        line_cnt = 0;

                        outputFile.Close();
                        output_filename = output_path + "\\" + string.Format("{0}", file_cnt) + ".txt";
                        outputFile = new StreamWriter(output_filename);


                        // 새로운 파일이 생성되면 진행도를 올린다.
                        progressBar1.Value = progressBar1.Value + 1;
                        progress_label.Text = (progressBar1.Value * 100 / progressBar1.Maximum).ToString() + " %";
                        Application.DoEvents();
                    }                   

                    // 읽은 파일을 저장한다.
                    outputFile.WriteLine(line);
                    line_cnt++;
                }
                // 파일을 닫는다.
                //outPutFile.WriteLine();
                inputFile.Close();
                outputFile.Close();

                // 작업 종료 로그를 찍는다.
                Log_print("파일 나누기 완료!!");                
            }
            catch
            {
                Log_print("[Error] 파일 나누기에 실패하였습니다!!");
            }
            return Output;
        }
        
        //--------------------------
        // 로그 -richTextBox
        //--------------------------
        private void Log_print(string str_msg)
        {
            filesplite_richTextBox.AppendText(str_msg + Environment.NewLine);
            filesplite_richTextBox.ScrollToCaret();
        }

댓글

💲 추천 글