앙큼한 개발기록

[C#] ini 파일 kernal로 읽고 쓰기 본문

개발

[C#] ini 파일 kernal로 읽고 쓰기

angkeum 2023. 5. 23. 20:05

url, host, serialport 등등 상수를 저장하고 해당 값을 호출 할때 

txt 파일과 ini 파일로 저장하여 데이터를 호출 및 저장하면 window 외부에서 파일을 열어 수정도 가능하고 

static한 데이터를 읽고 쓰고 수정하기 편리하다. 

 

txt파일도 일고 쓰기가 가능하지만 

key, value 쌍으로 가지고 있는 ini 파일이 읽고 쓰기가 더 편리하다. 

 

오늘은 ini 파일을 읽고 쓰는 코드를 정리해 보고자 블로그 글을 작성한다. 

소스 코드는 다음과 같다.

 

iniConfig.cs

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Newtonsoft.Json;

namespace Test.config
{
    static class IniConfig
    {
        private static readonly string CONFIG_FILE_PATH = Application.StartupPath + "\\config.ini";
        private const int MAX_LENGTH = 100;
        private const uint MAX_BUFFER = 0xffffffff;

        private const string SECTION = "Section_Name";
        private const string KEY = "KEY_NAME";
        private const string DEFAULT_VALUE = "TEST";

        private const string LIST_KEY = "LIST_KEY_NAME";
        private const string LIST_DEFAULT_VALUE = null;

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, uint size, string filePath);

        private static string key = "";
        private static List<CustomObject> list = null;

        public static string GetKey()
        {
            if (key.Length != 0)
            {
                return key;
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                int result = GetPrivateProfileString(SECTION, KEY, "", sb, MAX_LENGTH, CONFIG_FILE_PATH);
                if (result == 0)
                {
                    WritePrivateProfileString(SECTION, KEY, DEFAULT_VALUE, CONFIG_FILE_PATH);
                    return DEFAULT_VALUE;
                }
                else
                {
                    return sb.ToString();
                }
            }
        }

        public static void SetKey(string _key)
        {
            key = _key;
            WritePrivateProfileString(SECTION, KEY, DEFAULT_VALUE, CONFIG_FILE_PATH);
        }
        
        public static List<CustomObject> GetList()
        {
            if (list != null)
            {
                return list;
            }
            else
            {
                StringBuilder strBuilder = new StringBuilder();
                int result = GetPrivateProfileString(SECTION, LIST_KEY, "", strBuilder, MAX_BUFFER, CONFIG_FILE_PATH);
                if (result == 0)
                {
                    return new List<CustomObject>();
                }
                else
                {
                    return utils.JsonConverter.Deserialize<List<CustomObject>>(strBuilder.ToString()); 
                }
            }
        }

        public static void SetList(List<CustomObject> _list)
        {
            list = _list;
            string listJsonString = JsonConvert.SerializeObject(list).ToString();
            WritePrivateProfileString(SECTION, LIST_KEY, listJsonString, CONFIG_FILE_PATH);
        }
    }
}

 

c# 파일을 하나 만들어서 복사 붙여넣기 하면 바로 사용가능하다. 

위에의 "config.ini" 파일이 파일명이 되며 

프로젝트를 빌드하는 곳에 해당 값을 찾아서 생성 혹은 데이터를 가져 온다. 

 

ini 파일은 section, key, value로 구분 되며 

section 으로 나누어서 데이터를 가져올 수 있다. 

 

ini 파일의 내부는 다음과 같다. 

[Section_Name]
KEY_NAME=TEST
LIST_KEY_NAME=null // 만약 배열이 들어간다면 [{Custom Object}, {Custom Object}]

 

섹션은 여러개 생성 가능하고 

key 값은 띄어쓰기도 가능하다. (근데 띄어쓰기는 안쓰는걸 추천한다. 알아보기 어렵고 오타가 날 확률이 높다)

 

* 배열의 경우 JsonConverter를 사용하여 string을 json 값으로 바꾸어서 

사용한다. 

 

JsonConverter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test.utils
{
    public class JsonConverter
    {
        public static string Serialize<T>(in T data)
        {
            try
            {
                return Newtonsoft.Json.JsonConvert.SerializeObject(data);
            }
            catch { throw; }
        }

        public static byte[] SerializeUTF8<T>(in T data)
        {
            try
            {
                return Encoding.UTF8.GetBytes(Serialize(in data));
            }
            catch { throw; }
        }

        public static T Deserialize<T>(in string data)
        {
            try
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);
            }
            catch { throw; }
        }
    }
}

 

끝!

Comments