Nice programing

텍스트 파일의 문자 인코딩을 감지하는 방법은 무엇입니까?

nicepro 2020. 10. 24. 11:45
반응형

텍스트 파일의 문자 인코딩을 감지하는 방법은 무엇입니까?


내 파일에서 사용되는 문자 인코딩을 감지하려고합니다.

이 코드로 표준 인코딩을 시도합니다.

public static Encoding GetFileEncoding(string srcFile)
    {
      // *** Use Default of Encoding.Default (Ansi CodePage)
      Encoding enc = Encoding.Default;

      // *** Detect byte order mark if any - otherwise assume default
      byte[] buffer = new byte[5];
      FileStream file = new FileStream(srcFile, FileMode.Open);
      file.Read(buffer, 0, 5);
      file.Close();

      if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
        enc = Encoding.UTF8;
      else if (buffer[0] == 0xfe && buffer[1] == 0xff)
        enc = Encoding.Unicode;
      else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
        enc = Encoding.UTF32;
      else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
        enc = Encoding.UTF7;
      else if (buffer[0] == 0xFE && buffer[1] == 0xFF)      
        // 1201 unicodeFFFE Unicode (Big-Endian)
        enc = Encoding.GetEncoding(1201);      
      else if (buffer[0] == 0xFF && buffer[1] == 0xFE)      
        // 1200 utf-16 Unicode
        enc = Encoding.GetEncoding(1200);


      return enc;
    }

내 다섯 첫 번째 바이트는 60, 118, 56, 46 및 49입니다.

첫 번째 다섯 바이트와 일치하는 인코딩을 보여주는 차트가 있습니까?


BOM이있는 파일에 의존 할 수 없습니다. UTF-8에는 필요하지 않습니다. 그리고 비 유니 코드 인코딩에는 BOM이 없습니다. 그러나 인코딩을 감지하는 다른 방법이 있습니다.

UTF-32

BOM은 00 00 FE FF (BE의 경우) 또는 FF FE 00 00 (LE의 경우)입니다.

그러나 UTF-32는 BOM 없이도 쉽게 감지 할 수 있습니다. 이는 유니 코드 코드 포인트 범위가 U + 10FFFF로 제한되므로 UTF-32 단위는 항상 00 {00-10} xx xx (BE의 경우) 또는 xx xx {00-10} 00 (LE의 경우) 패턴을 갖기 때문입니다. . 데이터 길이가 4의 배수이고 이러한 패턴 중 하나를 따르는 경우 UTF-32라고 안전하게 가정 할 수 있습니다. 바이트 지향 인코딩에서 00 바이트의 희소성으로 인해 거짓 긍정은 거의 불가능합니다.

US-ASCII

BOM은 없지만 필요하지 않습니다. ASCII는 80-FF 범위의 바이트 부족으로 쉽게 식별 할 수 있습니다.

UTF-8

BOM은 EF BB BF입니다. 그러나 당신은 이것에 의존 할 수 없습니다. 많은 UTF-8 파일에는 특히 Windows가 아닌 시스템에서 생성 된 경우 BOM이 없습니다.

하지만 당신은 안전하게 UTF-8 등의 파일의 유효성을 검사하는 경우가 있다고 가정 할 수 있다 UTF-8. 거짓 양성은 드뭅니다.

특히 데이터가 ASCII가 아니라면 2 바이트 시퀀스의 오 탐률은 3.9 % (1920/49152)에 불과합니다. 7 바이트 시퀀스의 경우 1 % 미만입니다. 12 바이트 시퀀스의 경우 0.1 % 미만입니다. 24 바이트 시퀀스의 경우 백만 분의 1 미만입니다.

UTF-16

BOM은 FE FF (BE의 경우) 또는 FF FE (LE의 경우)입니다. UTF-16LE BOM은 UTF-32LE BOM의 시작 부분에 있으므로 먼저 UTF-32를 확인하십시오.

주로 ISO-8859-1 문자로 구성된 파일이있는 경우 파일 바이트의 절반이 00이면 UTF-16의 강력한 지표가됩니다.

그렇지 않으면 BOM없이 UTF-16을 인식하는 신뢰할 수있는 유일한 방법은 서로 게이트 쌍 (D [8-B] xx D [CF] xx)을 찾는 것이지만 BMP가 아닌 문자는이 방법을 실용적으로 만들기에는 너무 드물게 사용됩니다. .

XML

파일이 바이트 3C 3F 78 6D 6C (즉, ASCII 문자 "<? xml")로 시작하는 경우 encoding=선언 을 찾습니다 . 있는 경우 해당 인코딩을 사용합니다. 없으면 기본 XML 인코딩 인 UTF-8을 사용합니다.

EBCDIC를 지원해야하는 경우 동등한 시퀀스 4C 6F A7 94 93도 찾으십시오.

일반적으로 인코딩 선언이 포함 된 파일 형식이있는 경우 인코딩을 추측하지 말고 해당 선언을 찾으십시오.

해당 사항 없음

감지하는 데 더 많은 노력이 필요한 수백 가지 다른 인코딩이 있습니다. Mozilla의 문자 집합 탐지기 또는 .NET 포트를 사용하는 것이 좋습니다 .

합리적인 기본값

UTF 인코딩을 배제하고 다른 인코딩을 가리키는 인코딩 선언이나 통계적 탐지가없는 경우 ISO-8859-1 또는 밀접하게 관련된 Windows-1252를 가정 합니다. (최신 HTML 표준 에서는 "ISO-8859-1"선언을 Windows-1252로 해석해야합니다.) 영어 (및 스페인어, 포르투갈어, 독일어 및 프랑스어와 같은 기타 널리 사용되는 언어)에 대한 Windows의 기본 코드 페이지 여야합니다. UTF-8 이외의 가장 일반적으로 사용되는 인코딩입니다.


"간단한"해결책을 찾고자한다면 제가 함께 모은이 수업이 유용하다는 것을 알게 될 것입니다.

http://www.architectshack.com/TextFileEncodingDetector.ashx

먼저 BOM 감지를 자동으로 수행 한 다음 BOM이없는 유니 코드 인코딩과 다른 기본 인코딩 (일반적으로 Windows-1252, .Net에서 Encoding.ASCII로 잘못 레이블이 지정됨)을 구별하려고합니다.

위에서 언급했듯이 NCharDet 또는 MLang을 포함하는 "무거운"솔루션이 더 적절할 수 있으며이 클래스의 개요 페이지에서 언급했듯이 가능한 한 사용자와 상호 작용을 제공하는 것이 가장 좋습니다. 100 % 탐지율은 불가능합니다!


이를 사용 StreamReader하고 지시하여 인코딩을 감지하십시오.

using (var reader = new System.IO.StreamReader(path, true))
{
    var currentEncoding = reader.CurrentEncoding;
}

코드 페이지 식별자 https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx사용 하여 이에 따라 논리를 전환하십시오.


여기에 몇 가지 답변이 있지만 아무도 유용한 코드를 게시하지 않았습니다.

Here is my code that detects all encodings that Microsoft detects in Framework 4 in the StreamReader class.

Obviously you must call this function immediately after opening the stream before reading anything else from the stream because the BOM are the first bytes in the stream.

This function requires a Stream that can seek (for example a FileStream). If you have a Stream that cannot seek you must write a more complicated code that returns a Byte buffer with the bytes that have already been read but that are not BOM.

/// <summary>
/// UTF8    : EF BB BF
/// UTF16 BE: FE FF
/// UTF16 LE: FF FE
/// UTF32 BE: 00 00 FE FF
/// UTF32 LE: FF FE 00 00
/// </summary>
public static Encoding DetectEncoding(Stream i_Stream)
{
    if (!i_Stream.CanSeek || !i_Stream.CanRead)
        throw new Exception("DetectEncoding() requires a seekable and readable Stream");

    // Try to read 4 bytes. If the stream is shorter, less bytes will be read.
    Byte[] u8_Buf = new Byte[4];
    int s32_Count = i_Stream.Read(u8_Buf, 0, 4);
    if (s32_Count >= 2)
    {
        if (u8_Buf[0] == 0xFE && u8_Buf[1] == 0xFF)
        {
            i_Stream.Position = 2;
            return new UnicodeEncoding(true, true);
        }

        if (u8_Buf[0] == 0xFF && u8_Buf[1] == 0xFE)
        {
            if (s32_Count >= 4 && u8_Buf[2] == 0 && u8_Buf[3] == 0)
            {
                i_Stream.Position = 4;
                return new UTF32Encoding(false, true);
            }
            else
            {
                i_Stream.Position = 2;
                return new UnicodeEncoding(false, true);
            }
        }

        if (s32_Count >= 3 && u8_Buf[0] == 0xEF && u8_Buf[1] == 0xBB && u8_Buf[2] == 0xBF)
        {
            i_Stream.Position = 3;
            return Encoding.UTF8;
        }

        if (s32_Count >= 4 && u8_Buf[0] == 0 && u8_Buf[1] == 0 && u8_Buf[2] == 0xFE && u8_Buf[3] == 0xFF)
        {
            i_Stream.Position = 4;
            return new UTF32Encoding(true, true);
        }
    }

    i_Stream.Position = 0;
    return Encoding.Default;
}

Yes, there is one here: http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding.


You should read this: How can I detect the encoding/codepage of a text file


If your file starts with the bytes 60, 118, 56, 46 and 49, then you have an ambiguous case. It could be UTF-8 (without BOM) or any of the single byte encodings like ASCII, ANSI, ISO-8859-1 etc.


I use Ude that is a C# port of Mozilla Universal Charset Detector. It is easy to use and gives some really good results.

참고URL : https://stackoverflow.com/questions/4520184/how-to-detect-the-character-encoding-of-a-text-file

반응형