프로그램/C#

C# 디렉토리에 있는 csv 파일을 utf-8 bom 파일로 변경하기

더월드 2023. 11. 29.

엑셀에서 파일을 열 때, 일반적으로 BOM(Byte Order Mark)이 있는 UTF-8 파일을 인식합니다.
그래서 bom이 없는 csv 파일을 열었을때 한글 깨짐이 발생합니다.

 

1. 엑셀에서  "데이터" 탭에서 "텍스트 가져오기" 옵션을 사용하여 데이터를 가져올 때, 올바른 인코딩을 선택하여 열기를하여 수정하는 방법이 있고,

2. notepad++ 인코딩 메뉴에서 UTF-8 인코딩인것을 확인하고, 아래쪽에 있는 UTF-8 BOM으로 변환 메뉴를 선택하여 변경하는 방법도 있습니다.

 

상세 방법 : https://intotw.tistory.com/356

 

하지만, 여러개의 csv 파일을 변경하기 위해서는 프로그램으로 하면 편리합니다.

 

C#을 사용하여 디렉토리와 서버 디렉토리에 있는 CSV 파일들을 UTF-8 BOM으로 변경하는 코드입니다.

이 코드는 System.IO와 System.Text 네임스페이스를 사용합니다.

 

이 코드에서는 지정된 디렉토리 내의 모든 CSV 파일을 찾아서 각 파일을 UTF-8 BOM으로 변경합니다.

 

// UTF-8 인코딩에 BOM 추가
byte[] bom = Encoding.UTF8.GetPreamble();

 

bom을 추가후 기존 파일 내용을 읽어와서 붙임니다.

 

 코드를 사용하기 전에 디렉토리 경로를 적절히 수정해야 합니다.

//----------------------------------
// CSV to BOM file
//----------------------------------
private void CSVtoBom()
{
    // 디렉토리 경로 설정
    string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
    path = System.IO.Path.GetDirectoryName(path);
    string directoryPath = String.Format("{0}{1}", path, "\\Result");
    log_print(String.Format("csv folder: {0}", directoryPath));


    // 디렉토리 내 CSV 파일들에 대한 경로 가져오기
    string[] csvFiles = Directory.GetFiles(directoryPath, "*.csv", SearchOption.AllDirectories);

    // CSV 파일들을 UTF-8 BOM으로 변경
    foreach (var csvFile in csvFiles)
    {
        //log_print(String.Format("csv file list: {0}", csvFile));
		
        // BOM 추가 하기
        // 메모리 사용
        AddBomToCsv_overwrite(csvFile);
		
        // 대용량 파일시
        // 다른 파일에 적용
        //AddBomToCsv_target(csvFile, outFile);
        
        // 대용량 파일시
        // temp-> 기존 파일 대체
        //AddBomToCsv_temp(csvFile);
    }

    //log_print("Csv file -> Bom Conversion completed.");
}

private void AddBomToCsv_overwrite(string filePath)
{
    // UTF-8 인코딩에 BOM 추가
    byte[] bom = Encoding.UTF8.GetPreamble();

    // 기존 파일의 내용을 읽어오기
    byte[] fileContent = File.ReadAllBytes(filePath);

    // BOM과 기존 파일 내용 합치기
    byte[] newFileContent = new byte[bom.Length + fileContent.Length];
    Array.Copy(bom, newFileContent, bom.Length);
    Array.Copy(fileContent, 0, newFileContent, bom.Length, fileContent.Length);

    // 새로운 내용으로 파일 쓰기
    File.WriteAllBytes(filePath, newFileContent);
}

// 대용량 파일
private void AddBomToCsv_target(string sourceFilePath, string destinationFilePath)
{
    // UTF-8 인코딩에 BOM 추가
    byte[] bom = Encoding.UTF8.GetPreamble();

    // 소스 파일에서 읽기, 대상 파일에 쓰기
    using (var sourceStream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
    using (var destinationStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.Write))
    {
        // BOM 쓰기
        destinationStream.Write(bom, 0, bom.Length);

        // 소스 파일에서 읽어서 대상 파일에 쓰기
        byte[] buffer = new byte[4096]; // 조절 가능한 버퍼 크기
        int bytesRead;
        while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            destinationStream.Write(buffer, 0, bytesRead);
        }
    }
}

// 대용량 파일
// bom 추가 후 기존 파일 삭제
private void AddBomToCsv_temp(string filePath)
{
    // UTF-8 인코딩에 BOM 추가
    byte[] bom = Encoding.UTF8.GetPreamble();

    // 새로운 파일 경로 생성
    string tempFilePath = Path.Combine(Path.GetDirectoryName(filePath), "temp_" + Path.GetFileName(filePath));

    // 소스 파일에서 읽기, 새로운 파일에 쓰기
    using (var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    using (var destinationStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write))
    {
        // BOM 쓰기
        destinationStream.Write(bom, 0, bom.Length);

        // 소스 파일에서 읽어서 새로운 파일에 쓰기
        byte[] buffer = new byte[4096]; // 조절 가능한 버퍼 크기
        int bytesRead;
        while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            destinationStream.Write(buffer, 0, bytesRead);
        }
    }

    // 기존 파일 삭제
    File.Delete(filePath);

    // 새로운 파일 이름 변경
    File.Move(tempFilePath, filePath);
}

 

댓글

💲 추천 글