관리 메뉴


Kinesis´s Open Document

C# - 파일을 읽어들여 구분자 문자열(String)을 키(Key)로 활용하여 리스트 생성하기 예제 본문

MEMO/기술 자료/C# Language

C# - 파일을 읽어들여 구분자 문자열(String)을 키(Key)로 활용하여 리스트 생성하기 예제

Kinesis 2012. 3. 21. 16:22

앞서 문자열(String)을 키(Key)를 인덱스로 이용해 값(Value)을 가진 일종의 테이블을 만드는 방법에 대해 가볍게 확인해 보았다. Dictionary 라는 클래스 라이브러리를 통해 마치 배열인것 마냥 문자열 키를 인덱스처럼 써서 값을 대입하거나 사용하는 자체로도 편하지만 활용할 경우에 좀 더 편해질 수 있다.

주로 사용하는 메세지를 특정 파일안에 담아두고 이를 읽어와 문자열 키와 값으로 묶어 리스트를 만들어 두면 프로그램의 유지보수나 메세지 변경시에 해당 텍스트 내용만 바꿈으로 인해 어플리케이션 전체에 적용할 수 있으니 더욱 편해질 수 있다는 개념으로 말이다.

가령 message_error.msg 라는 이름의 텍스트 파일에 다음과 같이 내용을 작성해 넣었다고 치자.
;
;	주석처리 부분
;
Null	값이 비어있습니다.
NoneExists	{0} 파일이 존재하지 않습니다.
	시작이 구분자인 경우
또는 구분자가 아예 없는 경우
가능하다면 우리는 Msg["Null"] 과 같이 앞의 명칭만을 이용해 메세지를 출력하고 싶은 경우에는 어떻게 할 수 있을까? 바로 앞서 이용했던 Dictionary 를 이용해 하나의 메서드(함수)를 만들어 활용할 수 있을 것이다. 아래는 그렇게 활용할 수 있는 셈플 코드를 작성한 내용이다.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace MessageManager
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> Msg = new Dictionary<string, string>(); // 문자열 키를 인덱스로 사용하는 테이블을 생성하기 위해 선언

            String MessageListFile = @"Message_Error.msg"; // 메세지가 들어 있는 파일을 지정

            if (File.Exists(MessageListFile)) // 파일 존재 유무, 있으면 처리한다.
            {
                FileStream MessageFile = File.Open(MessageListFile, FileMode.OpenOrCreate, FileAccess.Read); // 파일을 열되 없다면 생성하고 권한은 읽기 전용으로 생성
                StreamReader MessageStream = new StreamReader(MessageFile); // 스트림 생성

                MessageStream.BaseStream.Seek(0, SeekOrigin.Begin); // 파일을 읽어가기 시작한다.

                while (MessageStream.Peek() > -1)
                {
                    String ReadLine = MessageStream.ReadLine(); // String형 변수에 파일 내의 한 줄을 읽어온다.
                    int SplitIndex = ReadLine.IndexOf("\t"); // Tab을 구분자로 두고 구분자를 기준으로 잘라내기 위해 인덱스를 얻는다.
                    if (SplitIndex == 0 || SplitIndex == -1 || ReadLine.StartsWith(";")) { continue; } // 맨 첫문자가 구분자이거나 또는 없거나, ; 로 시작하는 경우 스킵
                    Msg[ReadLine.Substring(0, SplitIndex).ToLower()] = ReadLine.Substring(SplitIndex + 1); // 테이블에 구분자 전의 값을 키, 후를 값으로 리스트를 생성한다.
                }

                MessageStream.Close();

                foreach (KeyValuePair<string, string> Message in Msg)
                {
                    Console.WriteLine("{0}\t{1}", Message.Key, Message.Value);
                }

                Console.WriteLine("\n" + Msg["NoneExists".ToLower()], "test.txt"); // {0} 과 같은 함수를 이용한 값 출력 테스트
            }
            else // 파일이 없으면 찾을 수 없다는 메세지 출력
            {
                Console.WriteLine("Error : Not Found MessageList File.");
            }
        }
    }
}
친절하게 주석까지 일일이 달아 놓았다. 일단 주의해서 봐두길 바라는 부분이 하나 있다.

첫째로 27번 줄이다. 해당 줄을 보면 특정 조건시 continue; 처리를 하도록 되어 있다. 이 부분이 없다면 ; 를 이용해 주석처리를 할 수 없고, 시작하는 문자가 구분자로 시작을 한다거나, 구분자가 없는 경우에 대한 처리가 하기 힘들어진다. (물론 이것도 완벽하게 처리해둔 것은 아니기에 실무에 사용하려면 어느정도 수정 보완이 필요하다는 것을 알아두자)

두번째로 28번째 줄과 38번째 줄이다. KEY 가 될 수 있는 부분을 .ToLower() 를 통해 소문자형태로 변환하도록 해두었다. 이유인즉 Key 가 되는 값은 대문자와 소문자를 구분하기때문에 Null 이라는 값으로 키를 생성했는데 사용할때 null 이라고 키를 불러오면 에러가 생길 수 있기 때문이다. 필요하다면 이 부분을 없애고 대소문자 구분을 받도록 하거나 대문자로만 활용하도록 바꾸거나 할 수도 있겠지만 이것은 전적으로 활용하는 사람이 어떻게 활용할거냐 라는 목적에 따라 달라질 수 있을 것이다.

또한 메세지를 만들때 미리 {0} {1} 과 같이 값이 들어갈 공간을 만들어 둔다면, 38번째 줄에서 인자값을 전달하는 방식으로도 활용할 수 있으니, 이 부분을 잘 알아둔다면 메세지 처리 부분을 더 잘 활용할 수 있을 것이다.

하여 최종적으로 결과를 보면 다음과 같은 화면을 볼 수 있다.


생성된 리스트가 "키 값" 으로 나와 있는 모습을 확인해 볼 수 있고, 4번째 줄에서(3번째 줄은 아무것도 없으니까) 인자값을 전달 받아 text.txt 라는 글자가 {0} 대신 대처되어 있는 모습을 확인해 볼 수 있다.

해당 소스에 대해 이해가 잘 안되고 있다면, Dictionary 및 File 처리 부분에 대한 내용을 좀 더 참고하면 쉽게 이해할 수 있다.


Comments