텍스트 파일의 인코딩 / 코드 페이지를 감지하는 방법 (수신 .txt, .csv다양한 소스

우리의 응용 프로그램에서, 우리는 텍스트 파일 (수신 .txt, .csv다양한 소스 등). 읽을 때 다른 / 알 수없는 코드 페이지에서 작성된 파일 때문에 이러한 파일에는 가비지가 포함되는 경우가 있습니다.

텍스트 파일의 코드 페이지를 (자동으로) 감지하는 방법이 있습니까?

detectEncodingFromByteOrderMarks의에 StreamReader생성자, 작동 UTF8 및 기타 유니 코드 표시 파일,하지만 난 같은 코드 페이지를 감지 할 수있는 방법을 찾고 있어요 ibm850, windows1252.


답변 해 주셔서 감사합니다. 이것이 제가 한 일입니다.

우리가받는 파일은 최종 사용자가 제공 한 것으로 코드 페이지에 대한 실마리는 없습니다. 수신자는 최종 사용자이기도합니다. 이제는 코드 페이지에 대해 알고 있습니다. 코드 페이지가 존재하며 성가 시게합니다.

해결책:

  • 받은 파일을 메모장에서 열고 깨진 텍스트를보십시오. 누군가 프랑수아 (François)라고 불리는 사람이 있다면 인간의 지능으로 추측 할 수 있습니다.
  • 사용자가 파일을 여는 데 사용할 수있는 작은 앱을 만들고 올바른 코드 페이지가 사용될 때 파일에 표시 될 텍스트를 입력합니다.
  • 모든 코드 페이지를 반복하고 사용자가 제공 한 텍스트로 솔루션을 제공하는 코드 페이지를 표시하십시오.
  • 하나 이상의 코드 페이지가 나타나면 사용자에게 더 많은 텍스트를 지정하도록 요청하십시오.


답변

코드 페이지를 감지 할 수 없으므로 알려야합니다. 바이트를 분석하고 추측 할 수는 있지만 기괴한 (때로는 재미있는) 결과를 줄 수 있습니다. 나는 지금 그것을 찾을 수 없지만 메모장이 중국어로 영어 텍스트를 표시하도록 속일 수 있다고 확신합니다.

어쨌든, 이것은 당신이 읽어야 할 것입니다 :
절대 최소 모든 소프트웨어 개발자는 절대적으로, 유니 코드와 문자 세트에 대해 알아야합니다 (변명 없음!) .

구체적으로 Joel은 말합니다.

인코딩에 관한 가장 중요한 사실

방금 설명한 모든 것을 완전히 잊어 버린 경우 매우 중요한 사실을 기억하십시오. 어떤 인코딩을 사용하는지 모른 채 문자열을 갖는 것은 의미가 없습니다. 더 이상 머리를 모래에 붙일 수 없으며 “일반”텍스트가 ASCII 인 것처럼 가장 할 수 없습니다. 일반 텍스트와 같은 것은 없습니다.

문자열, 메모리, 파일 또는 전자 메일 메시지가있는 경우 어떤 인코딩인지 알고 있어야합니다. 그렇지 않으면 해석하거나 사용자에게 올바르게 표시 할 수 없습니다.


답변

비 UTF 인코딩 (예 : BOM 없음)을 감지하려는 경우 기본적으로 텍스트의 휴리스틱 및 통계 분석을 따릅니다. 범용 문자셋 감지 ( Wayback Machine을 통한 더 나은 형식의 동일한 링크) 대한 Mozilla 백서를 살펴볼 수 있습니다 .


답변

Mozilla Universal Charset Detector에 C # 포트를 사용해 보셨습니까?

http://code.google.com/p/ude/의

public static void Main(String[] args)
{
    string filename = args[0];
    using (FileStream fs = File.OpenRead(filename)) {
        Ude.CharsetDetector cdet = new Ude.CharsetDetector();
        cdet.Feed(fs);
        cdet.DataEnd();
        if (cdet.Charset != null) {
            Console.WriteLine("Charset: {0}, confidence: {1}", 
                 cdet.Charset, cdet.Confidence);
        } else {
            Console.WriteLine("Detection failed.");
        }
    }
}    


답변

코드 페이지를 감지 할 수 없습니다

이것은 분명히 거짓입니다. 모든 웹 브라우저에는 어떤 종류의 인코딩도 표시하지 않는 페이지를 처리하는 일종의 범용 문자 집합 검출기가 있습니다. Firefox에는 하나가 있습니다. 코드를 다운로드하여 코드가 어떻게 작동하는지 확인할 수 있습니다. 여기에서 일부 문서를 참조 하십시오 . 기본적으로 휴리스틱이지만 실제로는 잘 작동합니다.

적당한 양의 텍스트가 주어지면 언어를 감지하는 것조차 가능합니다.

방금 Google을 사용하여 찾은 또 다른 것이 있습니다.


답변

나는이 질문에 매우 늦었다는 것을 알고 있으며 (영어 중심의 편견과 통계 / 실험 테스트가 없기 때문에)이 솔루션에 호소하지 않지만 특히 업로드 된 CSV 데이터를 처리하는 데 매우 효과적입니다.

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

장점 :

  • BOM 감지 내장
  • 사용자 정의 가능한 기본 / 대체 인코딩
  • UTF-8과 라틴 1 스타일 파일이 혼합 된 이국적인 데이터 (예 : 프랑스어 이름)가 포함 된 서유럽 기반 파일에 대해 상당히 신뢰할 만합니다 (기본적으로 미국과 서유럽 환경).

참고 : 저는이 수업을 썼던 사람이므로 소금 한 덩어리로 가져 가십시오! 🙂


답변

메모장 ++ 에는이 기능이 기본적으로 제공됩니다. 또한 변경을 지원합니다.


답변

다른 솔루션을 찾고 있는데

https://code.google.com/p/ude/

이 솔루션은 다소 무겁습니다.

4 바이트와 xml 문자 세트를 기반으로 한 기본적인 인코딩 감지가 필요했습니다. 그래서 인터넷에서 샘플 소스 코드를 가져 와서 약간 수정 된 버전을 추가했습니다.

http://lists.w3.org/Archives/Public/www-validator/2002Aug/0084.html

Java 용으로 작성되었습니다.

    public static Encoding DetectEncoding(byte[] fileContent)
    {
        if (fileContent == null)
            throw new ArgumentNullException();

        if (fileContent.Length < 2)
            return Encoding.ASCII;      // Default fallback

        if (fileContent[0] == 0xff
            && fileContent[1] == 0xfe
            && (fileContent.Length < 4
                || fileContent[2] != 0
                || fileContent[3] != 0
                )
            )
            return Encoding.Unicode;

        if (fileContent[0] == 0xfe
            && fileContent[1] == 0xff
            )
            return Encoding.BigEndianUnicode;

        if (fileContent.Length < 3)
            return null;

        if (fileContent[0] == 0xef && fileContent[1] == 0xbb && fileContent[2] == 0xbf)
            return Encoding.UTF8;

        if (fileContent[0] == 0x2b && fileContent[1] == 0x2f && fileContent[2] == 0x76)
            return Encoding.UTF7;

        if (fileContent.Length < 4)
            return null;

        if (fileContent[0] == 0xff && fileContent[1] == 0xfe && fileContent[2] == 0 && fileContent[3] == 0)
            return Encoding.UTF32;

        if (fileContent[0] == 0 && fileContent[1] == 0 && fileContent[2] == 0xfe && fileContent[3] == 0xff)
            return Encoding.GetEncoding(12001);

        String probe;
        int len = fileContent.Length;

        if( fileContent.Length >= 128 ) len = 128;
        probe = Encoding.ASCII.GetString(fileContent, 0, len);

        MatchCollection mc = Regex.Matches(probe, "^<\\?xml[^<>]*encoding[ \\t\\n\\r]?=[\\t\\n\\r]?['\"]([A-Za-z]([A-Za-z0-9._]|-)*)", RegexOptions.Singleline);
        // Add '[0].Groups[1].Value' to the end to test regex

        if( mc.Count == 1 && mc[0].Groups.Count >= 2 )
        {
            // Typically picks up 'UTF-8' string
            Encoding enc = null;

            try {
                enc = Encoding.GetEncoding( mc[0].Groups[1].Value );
            }catch (Exception ) { }

            if( enc != null )
                return enc;
        }

        return Encoding.ASCII;      // Default fallback
    }

아마도 파일에서 처음 1024 바이트를 읽는 것으로 충분하지만 전체 파일을로드하고 있습니다.