반응형
콜렉션을 넣어서 편하게 만들자
개인 프로젝트 작업 도중, 뽑아온 데이터 리스트를 CSV파일로 만들고 싶었는데, 종류가 너무 다양하여 이는 템플릿 형식으로 작성하게 되었습니다.
스크립트
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
internal static class Utils
{
public static string CSV_DATA_PATH = Path.Combine(Environment.CurrentDirectory, "Data");
private static StringBuilder sb = new StringBuilder();
/// <summary>
/// 경로에 폴더가 없으면 생성
/// </summary>
/// <param name="path"></param>
public static void CreatePathFolder(string path)
{
string[] folderNames = path.Split('\\');
string fullPath = string.Empty;
for (int i = 0; i < folderNames.Length - 1; i++)
{
fullPath += folderNames[i] + '\\';
DirectoryInfo di = new DirectoryInfo(fullPath);
if (!di.Exists) di.Create();
}
}
/// <summary>
/// 컬렉션 CSV 파일 만들기
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">컬렉션</param>
/// <param name="path">파일 위치</param>
/// <param name="overwrite">덮어쓰기 여부</param>
/// <param name="writeHeader">헤더 작성 여부</param>
/// <returns>작업 완료 여부</returns>
public static bool CreateCSVFile<T>(ICollection<T> collection, string path, bool overwrite = true, bool writeHeader = true)
{
try
{
if (collection.Count > 0)
{
CreatePathFolder(path);
sb.Length = 0;
path += ".csv";
if (!File.Exists(path) || overwrite)
{
// 텍스트 파일 생성
using (var writer = File.CreateText(path + ".temp"))
{
var enumerator = collection.GetEnumerator();
if (writeHeader)
{
// 1. 헤더 입력
if (enumerator.MoveNext())
{
FieldInfo[] fieldInfos = typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fieldInfos.Length; i++)
{
if (sb.Length > 0)
sb.Append(',');
sb.Append(fieldInfos[i].Name);
}
writer.WriteLine(sb);
}
}
// 2. 데이터 입력
enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
FieldInfo[] fieldInfos = typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fieldInfos.Length; i++)
{
if (i > 0) sb.Append(',');
sb.Append(fieldInfos[i].GetValue(enumerator.Current));
}
sb.Append('\n');
}
sb.Length -= 1;
writer.Write(sb);
writer.Close();
}
try
{
File.Delete(path);
}
catch { }
File.Move(path + ".temp", path);
return true;
}
else
Console.WriteLine("이미 파일이 존재합니다.");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return false;
}
/// <summary>
/// 텍스트 파일 열기
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string[,] OpenCSVFile(string path)
{
try
{
path += ".csv";
if (File.Exists(path))
{
string[] strs = File.ReadAllLines(path);
if (strs != null && strs.Length > 0)
{
int col = strs[0].Split(',').Length;
int row = strs.Length;
string[,] result = new string[row, col];
for (int i = 0; i < result.GetLength(0); i++)
{
string[] split = strs[i].Split(',');
for (int j = 0; j < result.GetLength(1); j++)
{
result[i, j] = split[j];
}
}
return result;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
/// <summary>
/// 경로상의 모든 폴더 및 하위 파일 삭제 시도
/// </summary>
public static void DeleteDirectory(string path)
{
try
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Directory.Delete(path, true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(path, true);
}
}
catch { }
}
}
예제
static void Main(string[] args)
{
string path = Path.Combine(Environment.CurrentDirectory, "Data", name);
bool create = Utils.CreateCSVFile(<리스트>, path, overwrite: false);
if (!create)
Utils.AppendCSVFile(collection, path);
}
예제 내용과 같이 List<T> 또는 Array를 넣어주면 해당 프로젝트 프로그램이 있는 파일이 위치해 있는 곳에 "Data" 파일 안에서 생성 됩니다.
마무리
기본적으로 덮어쓰기 옵션이 True가 되어있으니 사용에 참고바랍니다. :)
반응형
'Utils' 카테고리의 다른 글
C#, List 랜덤으로 섞기 확장함수 (Shuffle) (1) | 2022.10.24 |
---|---|
C#, 중복되지 않게 랜덤 숫자 생성 (0) | 2022.08.22 |
C# Windowform, 유니티처럼 코루틴 만들어서 사용하기 (2) | 2022.07.17 |
C#, 64비트 초과 비트연산자용 구조체 ShiftComparer (0) | 2022.07.04 |
Unity, 플레이 모드가 아닌 상태에서 코루틴 사용하기 (2) | 2022.04.06 |
댓글