CSV는 “그냥 텍스트”가 아니다 ── C# 업무 앱의 CSV 실무(문자 코드・Excel 호환・인젝션 대책)
· Go Komura · CSharp, .NET, CSV, Excel, 문자 코드, 파일 연동, Windows 개발, 기술 상담
CSV를 통한 데이터 연동은 업무 앱의 세계에서 지금도 현역 주역입니다. 그리고 “텍스트를 쉼표로 이어붙일 뿐”으로 보이기 때문에, 직접 만든 파서가 필드 내 쉼표 때문에 깨지거나, Excel로 열면 문자가 깨지거나, 전화번호의 앞자리 0이 사라지는 등의 사고가 반복적으로 일어나는 영역이기도 합니다.
이 글에서는 C#으로 CSV를 읽고 쓰는 업무 앱을 상정하여, CSV의 사양(RFC 4180)과 현실의 방언, 문자 코드 결정 방법, Excel과의 궁합 문제, CSV 인젝션 대책, 운영상의 함정까지 실무에서 판단하기 어려운 순서로 정리합니다.
1. 먼저 결론(판단표)
CSV의 설계 판단은 “누가(무엇이) 그 파일을 여는가”에서부터 거꾸로 계산합니다.
| 용도 | 문자 코드 1순위 후보 | 설계상의 핵심 |
|---|---|---|
| 사람이 Excel에서 더블클릭으로 여는 경우 | UTF-8(BOM 있음) | BOM이 없으면 Excel이 문자 코드를 잘못 인식해 문자가 깨지는 환경이 있다. 선행 0・날짜화 문제는 문자 코드로는 막을 수 없다(5장) |
| 신규 시스템 간 연동 | UTF-8(BOM 없음) | 문자 코드・따옴표・줄바꿈 코드・헤더 유무를 사양서에 명기한다. BOM 유무도 명기한다 |
| 레거시 시스템과의 연동 | 상대방 사양을 따른다(Shift_JIS가 많음) | .NET(Core)에서는 Shift_JIS에 CodePagesEncodingProvider 등록이 필요(4장). 기종 의존 문자의 처리를 먼저 정해둔다 |
| 대량 데이터의 배치 연동 | 사양을 따른다 | 전체를 메모리에 올리지 않고 한 줄씩 스트리밍으로 처리한다(7장). 배타 제어와 작성 중인 파일의 처리도 설계한다 |
| 사람이 Excel로 보거나 인쇄하는 것이 주목적 | ── | 애초에 CSV가 아니라 xlsx 출력을 검토한다(FAQ 참조) |
결론을 먼저 적습니다.
String.Split(',')로 하는 CSV 파싱은 동작하는 것처럼 보여도 사양상 깨집니다. 필드 내의 쉼표・줄바꿈・따옴표를 처리할 수 없기 때문입니다. .NET 표준 범위라면TextFieldParser를 사용하세요(3장).- 문자 코드 사고는 “Excel이 어떻게 해석하는가”에서 발생합니다. 사람이 Excel로 여는 CSV는 BOM 있는 UTF-8로 하는 것이 현재로서는 무난한 선택입니다. 또한 .NET에서 BOM을 붙일지 여부는
Encoding지정 방법에 따라 달라진다는 함정이 있습니다(4장). - .NET(Core)에서는 Shift_JIS를 추가 패키지 없이는 사용할 수 없습니다.
System.Text.Encoding.CodePages패키지의CodePagesEncodingProvider를 등록해야 비로소Encoding.GetEncoding("shift_jis")가 성공합니다. .NET Framework에서 이행한 CSV 처리가 운영 환경에서 처음으로 예외를 발생시키는 전형적인 포인트입니다. - 선행 0 소실・날짜화는 CSV 쪽에서는 막을 수 없습니다. 큰따옴표로 감싸도 막을 수 없다는 것이 중요한 사실입니다(5장).
- 사용자 입력을 CSV로 출력하는 앱은 CSV 인젝션 대책이 필요합니다.
=나+로 시작하는 필드는 Excel에서 수식으로 해석됩니다(6장).
2. CSV의 “사양” ── RFC 4180과 현실의 방언
CSV에는 사실상의 표준으로 RFC 4180이 있습니다1. 실무에서 알아두어야 할 규칙은 다음 4가지뿐입니다.
- 레코드의 구분은 줄바꿈(CRLF), 필드의 구분은 쉼표.
- 필드에 쉼표・줄바꿈・큰따옴표가 포함된 경우, 해당 필드 전체를 큰따옴표로 감싼다.
- 필드 내의 큰따옴표는
""와 같이 2개를 겹쳐서 이스케이프한다. - 감쌀 필요가 없는 필드는 감싸도 되고 감싸지 않아도 된다.
즉, 다음 한 줄은 3개 필드로 이루어진 레코드입니다.
1001,"株式会社サンプル 営業部","住所は""東京都○○区1-2-3""です,と入力された備考"
그리고 RFC 4180은 어디까지나 “사실상의 표준”이며, 현실의 CSV에는 방언이 산더미처럼 많습니다. 줄바꿈이 LF뿐이거나, 따옴표 처리를 하지 않거나, 구분자가 탭이나 세미콜론이거나, 헤더 행이 있거나 없거나──그렇기 때문에 연동 사양서에 “RFC 4180 준수”라는 한마디와 함께 문자 코드・BOM・줄바꿈 코드・헤더 유무를 명기하는 것이 나중의 트러블을 막는 데 가장 비용 대비 효과가 높은 작업이 됩니다.
3. Split(‘,’)로 직접 구현해서는 안 된다 ── 읽기의 실무
앞 장의 규칙을 감안하면 String.Split(',')가 깨지는 이유는 명백합니다. 필드 내의 쉼표 때문에 불필요하게 분할되고, 따옴표 안의 줄바꿈 때문에 행이 도중에 잘립니다. “지금 들어오는 파일에는 쉼표가 들어간 데이터가 없어서 동작하고 있을 뿐”이며, 데이터에 따라 언제든지 깨질 수 있습니다.
.NET 표준 범위에서 올바르게 읽으려면 Microsoft.VisualBasic.FileIO.TextFieldParser를 사용할 수 있습니다. 네임스페이스는 Visual Basic이지만 C#에서도 문제없이 사용할 수 있습니다.
using Microsoft.VisualBasic.FileIO; // Microsoft.VisualBasic.Core(Windows 데스크톱용 SDK에 포함됨)
using var parser = new TextFieldParser(path, System.Text.Encoding.UTF8)
{
TextFieldType = FieldType.Delimited,
HasFieldsEnclosedInQuotes = true, // 따옴표로 감싼 필드를 올바르게 처리한다
TrimWhiteSpace = false, // 기본값은 true(앞뒤 공백이 자동으로 제거됨). 공백이 의미를 갖는 데이터에서는 비활성화한다
};
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
try
{
string[]? fields = parser.ReadFields();
if (fields is null) break;
// fields[0], fields[1], ... 을 처리한다
}
catch (MalformedLineException ex)
{
// 잘못된 행: ErrorLine / ErrorLineNumber로 내용과 행 번호를 기록할 수 있다
logger.LogWarning("CSVの{Line}行目が不正な形式です: {Content}",
ex.LineNumber, parser.ErrorLine);
}
}
TextFieldParser의 실무상 장점은 따옴표 처리(HasFieldsEnclosedInQuotes)에 더해, 깨진 행을 MalformedLineException으로 행 번호와 함께 검출할 수 있다는 점입니다. 업무용 CSV 가져오기에서는 “한 줄이라도 깨져 있으면 파일 전체를 거부할 것인가, 그 줄만 건너뛰고 보고할 것인가”가 사양의 갈림길이 되므로, 이 예외 처리 설계를 그대로 사양에 반영할 수 있습니다.
열과 객체의 매핑・타입 변환・수백만 행 규모의 성능까지 필요하다면, 실적 있는 CSV 라이브러리(NuGet에서 널리 사용되는 것)의 도입을 검토하세요. 어떤 라이브러리를 선택하든 확인해야 할 관점은 “RFC 4180의 따옴표 처리”, “문자 코드 지정”, “깨진 행의 처리”, “스트리밍 읽기 가능 여부”의 4가지입니다.
쓰기 쪽은 사양이 단순하므로 직접 구현도 현실적이지만, 이스케이프 처리는 반드시 하나의 함수로 집약하세요.
// 쓰기 측 이스케이프는 이 함수 하나로 집약한다
static string ToCsvField(string? value)
{
value ??= string.Empty;
bool needsQuoting = value.Contains(',') || value.Contains('"')
|| value.Contains('\r') || value.Contains('\n');
return needsQuoting ? $"\"{value.Replace("\"", "\"\"")}\"" : value;
}
“금액 칼럼만 손으로 string.Join을 하고 있는 부분”이 단 한 곳이라도 남아 있으면, 그곳이 미래의 사고 현장이 됩니다.
4. 문자 코드 ── Excel의 동작과 .NET의 함정
4.1 Excel에서 열 것이라면 BOM 있는 UTF-8
CSV 문자 깨짐의 대부분은 Excel이 파일의 문자 코드를 잘못 인식하는 데서 발생합니다. BOM(파일 맨 앞에 붙는 몇 바이트의 표식)이 없는 UTF-8 CSV를 더블클릭으로 열면, 환경에 따라 ANSI(일본어 환경에서는 Shift_JIS)로 해석되어 일본어가 전부 깨집니다. BOM이 있는 UTF-8이면 UTF-8로 인식되므로, 사람이 Excel에서 더블클릭으로 여는 CSV는 BOM 있는 UTF-8로 만드는 것이 현재로서는 무난한 선택입니다.
여기에 .NET 쪽의 함정이 겹칩니다. BOM이 붙는지 여부는 Encoding을 전달하는 방식에 따라 달라집니다.
// BOM 없는 UTF-8: 인코딩 지정을 생략했을 때의 기본값
File.WriteAllText(path, csv);
// BOM 있는 UTF-8: Encoding.UTF8(정적 속성)은 BOM을 출력하도록 설정되어 있다
File.WriteAllText(path, csv, Encoding.UTF8);
// 의도를 명시하고 싶다면 생성자로 지정하는 편이 오해가 없다
File.WriteAllText(path, csv, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
Encoding.UTF8을 전달했을 때와 생략했을 때 결과 파일이 달라진다는 것은 모르면 알아차리기 어려운 사양입니다. “시스템 간 연동은 BOM 없음”, “Excel용은 BOM 있음”을 사양으로 정했다면, 코드에서도 new UTF8Encoding(...)으로 의도를 명시할 것을 권장합니다.
4.2 .NET(Core)에서 Shift_JIS를 사용하려면 등록이 필요
레거시 시스템과의 연동에서는 지금도 Shift_JIS(코드 페이지 932)의 CSV가 현역으로 쓰이고 있습니다. 여기서 중요한 것은 .NET(Core)/.NET 5 이후는 기본적으로 Unicode 계열과 ASCII 등 극히 일부의 인코딩만 지원한다는 점입니다. Encoding.GetEncoding("shift_jis")는 System.Text.Encoding.CodePages 패키지를 추가하고 CodePagesEncodingProvider를 등록하기 전까지는 예외를 발생시킵니다.
using System.Text;
// 앱 시작 시 한 번만 등록한다(Program.cs 등)
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// 이제 Shift_JIS(코드 페이지 932)를 가져올 수 있게 된다
Encoding sjis = Encoding.GetEncoding("shift_jis");
.NET Framework 시대의 CSV 처리를 .NET으로 이행한 앱이 운영 환경에서 처음으로 Shift_JIS 파일을 받아 예외를 발생시키는──사고의 단골 포인트입니다. 이행 시 점검 관점은 “.NET Framework를 .NET으로 이행하기 전에 확인해야 할 것“에 정리되어 있습니다.
또한 Shift_JIS를 사용하는 이상, 기종 의존 문자(①나 ㈱ 등)・물결표(波ダッシュ) 문제・Unicode에만 있는 문자의 누락은 피할 수 없습니다. 이와 관련된 문자 코드의 기초는 “Windows의 문자 코드를 정리한다“와 “Windows의 문자 코드와 개행 코드를 정리한다“에서 자세히 설명하고 있습니다.
5. Excel로 열면 깨지는 데이터 ── 선행 0・날짜화・지수 표기
문자 코드를 올바르게 해도 Excel에서의 열람에는 또 하나의 문제군이 있습니다. Excel은 CSV를 열 때 값을 “해석”한다는 것입니다.
| 원본 데이터 | Excel에서의 표시 | 무슨 일이 일어났는가 |
|---|---|---|
090123456xx(전화번호) |
90123456xx |
숫자로 해석되어 앞자리 0이 사라짐 |
007(상품 코드) |
7 |
위와 동일 |
1-1(가지번호) |
1월 1일 |
날짜로 해석됨 |
1234567890123456(16자리 관리 번호) |
1.23457E+15 |
지수 표기가 되어 하위 자릿수가 손실됨 |
그리고 중요한 것은 이들은 필드를 큰따옴표로 감싸도 막을 수 없다는 점입니다. 따옴표는 CSV의 구문상 구분을 나타낼 뿐이며, Excel은 내용을 다시 해석합니다.
실무상의 대처는 다음 3가지 중 하나입니다.
- Excel 쪽에서 올바른 절차로 열도록 한다. 더블클릭이 아니라 Excel의 “데이터 가져오기(텍스트/CSV에서)”에서 열의 형식을 “문자열”로 지정해서 읽으면 깨지지 않습니다. 운영 절차서에 적어둘 가치가 있습니다.
- 열람이 주목적이라면 xlsx로 출력한다. 셀 서식을 출력 측에서 제어할 수 있으므로 이 문제군이 근본적으로 사라집니다. Excel 파일 출력을 만드는 방법은 “Excel 장표 출력을 어떻게 만들까“를 참조하세요. 또한 서버나 서비스에서의 Excel COM 자동화는 권장되지 않으며, “C#의 Excel 조작에서 EXCEL.EXE가 남는 문제“에서 설명한 대로 프로세스가 잔류하는 온상이 되므로 라이브러리 기반의 출력을 선택하세요.
="007"형식으로 출력하는 것은 최후의 수단이다. Excel로 열면 문자열로 표시되는 우회 기법이지만, CSV로서는 “수식이 포함된 비표준 파일”이 되어 Excel 이외의 가져오기 대상을 망가뜨립니다. 다른 시스템과 겸용하는 파일에서는 사용하지 마세요.
6. CSV 인젝션 ── 사용자 입력을 수식으로 만들지 않는다
사용자가 입력한 값(이름・비고・주소 등)을 CSV로 출력해 Excel로 열게 하는 앱에는 CSV 인젝션이라는 공격 경로가 있습니다. =・+・-・@ 등으로 시작하는 필드를 Excel이 수식으로 해석하기 때문에, 악의적인 입력(예: =cmd|'/C calc'!A0처럼 외부 프로세스 실행을 노리는 수식)이 CSV를 연 다른 사용자의 환경에서 실행될 수 있다는 문제입니다.
대책의 기본은 출력 시 위험한 선행 문자를 무해화하는 것입니다.
// 수식으로 해석될 수 있는 필드의 앞에 작은따옴표를 붙인다.
// 일본어 환경에서는 전각 문자인 =+-@도 수식의 시작으로 해석될 수 있으므로 대상에 포함한다
static string SanitizeForExcel(string value)
{
if (value.Length > 0 && value[0]
is '=' or '+' or '-' or '@' or '\t' or '\r' or '\n'
or '=' or '+' or '-' or '@')
{
return "'" + value;
}
return value;
}
앞에 붙는 작은따옴표는 Excel에서 “문자열로 취급한다”는 표시가 됩니다. 다만 위험한 선행 문자의 목록은 표 계산 소프트웨어의 구현・버전에 따라 달라질 수 있으므로, 이러한 무해화는 “선행 문자가 이 허용 목록(영숫자 등)에 일치하는 경우에만 그대로 통과시킨다”는 방향으로 설계하면 예상치 못한 누락에 강해집니다. 다만 다른 시스템이 그 CSV를 가져오는 경우에는 작은따옴표가 데이터로 남는다는 점에 주의가 필요하며, “Excel에서 열기용”과 “시스템 가져오기용”으로 파일을 나누는 판단도 있을 수 있습니다. 입력값 검증(애초에 선행 =를 허용하지 않는 등)과 조합할지 여부도 포함해, 앱 전체의 보안 설계는 “Windows 앱 개발에서 최저한의 보안을 지키기 위한 체크리스트“를 참조하세요.
7. 운영상의 함정 ── 포맷 이외에서 사고가 나는 지점
마지막으로 CSV 자체의 구문 이외에서 실무 사고가 일어나는 포인트를 정리합니다.
- 숫자・날짜의 포맷을 OS의 컬처(culture)에 의존시키지 않는다.
value.ToString()은 OS의 지역 설정의 영향을 받습니다. 소수점이 쉼표인 지역 설정에서는1,5로 출력되어 CSV의 구분자와 충돌합니다. 파일 연동용 변환은CultureInfo.InvariantCulture를 명시하고, 날짜는yyyy-MM-dd와 같은 고정 서식으로 하세요. 날짜 설계는 “업무 앱의 날짜/시간과 시간대“에서 자세히 다루고 있습니다. - 대량 데이터는 스트리밍으로 처리한다 ── 다만 “한 줄씩”으로 괜찮은지는 사양에 달려 있다.
File.ReadAllLines는 모든 행을 배열로 메모리에 올리기 때문에 큰 파일에는 적합하지 않습니다. 여기서File.ReadLines(지연 열거)나StreamReader의 줄 단위 읽기로 대체해도 되는 것은 필드 내의 줄바꿈을 허용하지 않는다고 사양에 명기된 파일뿐입니다. 따옴표 안의 줄바꿈을 허용하는 RFC 4180 준수 CSV에서는 줄 단위 분할이 하나의 레코드를 도중에 절단합니다. 이 경우에는 파일 경로에서 직접 읽는TextFieldParser(전체를 메모리에 올리지 않고 처리 가능)나 CSV 라이브러리의 스트리밍 읽기를 사용하세요. - “작성 중인 파일”을 읽게 하지 않고・읽지 않는다. 출력 측은 임시 파일명으로 쓴 뒤 이름을 바꾸고, 가져오는 측은 배타를 확인한 뒤 읽는다──이 파일 연동의 기본 형태는 “파일 연계의 배타 제어 기초 지식“에, 폴더 감시로 가져오는 경우의 주의점은 “FileSystemWatcher 사용법과 주의점“에 정리되어 있습니다.
- 열의 증감에 대비한다. “헤더 행의 열 이름으로 매핑한다”인지 “열 순서 고정・열 개수 확인 후 불일치 시 거부한다”인지를 사양으로 명기합니다. 암묵적인
fields[7]과 같은 매직 넘버 참조는 연동 대상의 사소한 열 추가로 조용히 깨집니다. - 말미 줄바꿈과 빈 줄의 처리를 미리 정해둔다. 마지막 행 뒤에 줄바꿈이 있는지, 빈 줄을 건너뛸지 거부할지는 파서 구현에 따라 동작이 갈리는 부분입니다.
TextFieldParser는 빈 줄을 건너뜁니다.
정리
CSV는 “쉼표로 구분할 뿐”이라는 얼굴을 하고 있는, 방언투성이의 연동 포맷입니다. 실무의 핵심은 4가지──읽기는 따옴표 처리가 가능한 부품을 사용한다(Split으로 직접 구현하지 않는다), 문자 코드는 여는 상대(특히 Excel)에서 거꾸로 계산해 정하고 BOM 유무까지 사양에 적는다, Excel의 값 해석(0 소실・날짜화)은 CSV 쪽에서는 막을 수 없다는 것을 안다, 사용자 입력을 출력한다면 인젝션 대책을 넣는다──이것만으로 CSV 연동 사고의 대부분은 설계 단계에서 막을 수 있습니다.
기존 CSV 연동의 문자 깨짐이나 데이터 손상 조사, 레거시 시스템과의 연동 사양 정리, CSV 가져오기・출력 기능의 신규 구현은 실제 파일과 연동 대상의 사양을 확인하면서 판단해야 하는 경우가 많으므로, 판단이 서지 않으면 상담해 주세요.
관련 글
- Windows의 문자 코드를 정리한다
- Windows의 문자 코드와 개행 코드를 정리한다
- Excel 장표 출력을 어떻게 만들까
- C#의 Excel 조작에서 EXCEL.EXE가 남는 문제
- 파일 연계의 배타 제어 기초 지식
- FileSystemWatcher 사용법과 주의점
- 업무 앱의 날짜/시간과 시간대
- .NET Framework를 .NET으로 이행하기 전에 확인해야 할 것
- Windows 앱 개발에서 최저한의 보안을 지키기 위한 체크리스트
관련 상담 분야
고무라소프트 합동회사에서는 CSV・파일 연동을 포함한 업무 앱 개발, 기존 연동의 문자 깨짐・데이터 손상 원인 조사, 레거시 시스템과의 연동 사양 정리에 관한 기술 상담을 다루고 있습니다.
참고 자료
-
IETF, RFC 4180 - Common Format and MIME Type for Comma-Separated Values (CSV) Files. CSV의 사실상 표준 사양. 필드 내 쉼표・줄바꿈・큰따옴표의 따옴표 처리,
""에 의한 이스케이프에 대해. ↩
관련 기사
같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.
WinForms/WPF 앱 다국어화 ── resx·새틀라이트 어셈블리·컬처 전환 실무
Windows 데스크톱 앱의 다국어화를 CurrentCulture와 CurrentUICulture의 차이, resx와 새틀라이트 어셈블리를 통한 리소스 구조, WinForms의 Localizable 속성, WPF에서의 현실적인 방식 선택, 실행 ...
HttpClient를 using으로 감싸면 안 되는 이유 ── C# 업무 앱의 HTTP 통신 실무(생성 패턴・타임아웃・재시도)
C#의 HttpClient를 매번 using으로 생성하면 소켓 고갈이, static으로 만들면 DNS 변경을 따라가지 못하는 문제가 발생합니다──이 두 가지 큰 문제의 구조와, PooledConnectionLifetime・IHttpClientFa...
PerfView와 dotnet-trace로 “느림”의 원인을 찾는다 ── .NET 성능 조사 실무 입문
업무 앱이 “느리다”, “CPU를 다 써버린다”, “가끔 멈춘다”고 할 때, 어떤 도구로 무엇을 봐야 할까요. PerfView와 dotnet-trace의 역할 분담, CPU 샘플링을 읽는 방법(inclusive/exclusive), ThreadT...
appsettings.json만으로는 부족하다 ── Windows 업무 앱 구성 관리 실무(환경별 설정・비밀 정보・쓰기 위치)
Windows 업무 앱의 구성 관리를 appsettings.json의 계층화, IConfiguration과 IOptions/IOptionsSnapshot/IOptionsMonitor의 구분 사용, 환경별 설정, 쓰기 가능한 설정의 배치 위치, 비...
Windows 업무 앱의 인쇄와 PDF 출력 - System.Drawing.Printing / WPF / 보고서 라이브러리 구분 사용법
PrintDocument를 이용한 WinForms 인쇄, WPF의 FlowDocument/FixedDocument 인쇄, PDF 출력의 선택지를 요구사항별 판단표로 정리합니다. 페이지 나눔 제어나 DPI 차이 같은 구현의 함정, Windows 서...
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
Windows 앱 개발
CSV를 통한 시스템 간 연동・장표 출력의 설계와 구현은 Windows 앱 개발의 실무 상담 범위에 해당하기 때문입니다.
기술 상담 & 설계 리뷰
기존 CSV 연동에서 발생하는 문자 깨짐・데이터 손상의 원인 조사와 사양 정리는 설계 리뷰를 수반하는 기술 상담에 해당하기 때문입니다.
자주 묻는 질문
이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.
- CSV의 문자 코드는 무엇으로 해야 하나요?
- 받는 쪽이 정해져 있다면 받는 쪽의 사양에 맞추는 것이 대원칙입니다. 새로 정할 수 있는 경우, 사람이 Excel로 여는 파일은 BOM 있는 UTF-8, 시스템 간 연동은 BOM 없는 UTF-8로 사양서에 명기하는 것이 무난한 출발점입니다. 레거시 시스템과의 연동에서 Shift_JIS를 요구받은 경우, 기종 의존 문자나 외자 문자의 처리를 먼저 정해두지 않으면 나중에 문자 깨짐의 책임 문제가 됩니다.
- CSV 라이브러리를 도입해야 하나요, 아니면 직접 구현해도 되나요?
- 읽기에 관해서는, 직접 만든 String.Split으로는 사양상 올바르게 처리할 수 없는 경우(필드 내의 쉼표・줄바꿈・따옴표)가 있으므로 어떤 형태로든 부품을 사용해야 합니다. .NET 표준 범위라면 TextFieldParser가 RFC 4180에 준하는 따옴표 처리를 지원합니다. 열과 객체의 매핑, 타입 변환, 대량 데이터의 성능까지 요구한다면 실적 있는 CSV 라이브러리 도입을 검토하세요. 쓰기는 사양이 단순한 만큼 직접 구현도 현실적이지만, 따옴표 이스케이프용 공통 함수를 하나 마련해 전부 그곳을 거치도록 하세요.
- 쉼표 구분이 아니라 탭 구분(TSV)으로 해야 하나요?
- 데이터에 쉼표가 자주 나오는 경우(주소・성명・금액 표기 등) TSV로 하면 따옴표 처리 빈도가 줄어들고 육안 확인도 쉬워집니다. 다만 탭이나 줄바꿈이 데이터에 들어갈 수 있다는 점은 동일하며, 따옴표 처리가 불필요해지는 것은 아닙니다. "TSV니까 구분 문자를 고려할 필요가 없다"는 것은 아니라는 점에 주의하세요. 연동 대상과 합의할 수 있다면, 구분 문자보다 "문자 코드・따옴표・줄바꿈 코드・헤더 유무를 사양서에 명기하는 것"이 사고 방지에 더 효과적입니다.
- Excel에서 여는 것이 목적이라면 CSV가 아니라 Excel 파일을 출력해야 하나요?
- "사람이 Excel로 보고・인쇄하는 것"이 주목적이라면 xlsx 형식으로 출력하는 것을 검토할 가치가 있습니다. CSV는 Excel로 여는 순간 선행 0 소실이나 날짜화가 발생하는 형식이며, 이를 CSV 쪽에서 완전히 막을 방법은 없습니다. xlsx라면 셀 서식을 출력 측에서 제어할 수 있습니다. 반면 다른 시스템으로의 가져오기가 주목적이고 Excel에서의 열람은 부수적이라면, CSV 그대로 두고 "가져오기 절차(데이터 가져오기 기능을 사용)"를 운영 절차로 안내하는 편이 현실적입니다.
저자 프로필
기사 저자의 프로필 페이지입니다.
Go Komura
합동회사 코무라소프트 대표
Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.
공개 링크