우리의 응용 프로그램에서, 우리는 텍스트 파일 (수신 .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 바이트를 읽는 것으로 충분하지만 전체 파일을로드하고 있습니다.