신청서에는 텍스트 파일 (.txt
,.csv
, 등). 이 파일을 읽을 때 다른 / 알 수없는 코드 페이지에서 작성된 파일이기 때 문에 가비지가 포함되는 경우가 있습니다.
텍스트 파일의 코드 페이지를 (자동으로) 감지하는 방법이 있습니까?
그만큼detectEncodingFromByteOrderMarks
,에StreamReader
생성자, 작품UTF8
및 기타 유니 코드 표시된 파일,하지만 코드 페이지를 검색 할 수있는 방법을 찾고 있어요.ibm850
,windows1252
.
귀하의 답변을 주셔서 감사합니다, 이것은 내가 한 짓입니다.
우리가받는 파일은 최종 사용자가 제공하는 코드 페이지에 대한 단서가 없습니다. 리시버는 최종 사용자이기도합니다. 지금은 코드 페이지에 대해 알고있는 내용입니다. 코드 페이지가 있고 성가시다.
해결책:
코드 페이지를 감지 할 수 없으므로이를 알려야합니다. 바이트를 분석하고 추측 할 수 있지만, 기괴한 (때로는 재미있는) 결과를 줄 수 있습니다. 지금은 찾을 수 없지만 메모장을 속여서 중국어로 영어 텍스트를 표시 할 수는 있습니다.
어쨌든, 이것은 당신이 읽을 필요가있는 것입니다 :절대적으로 모든 소프트웨어 개발자가 절대적으로, 절대적으로 유니 코드와 문자 집합에 대해 알아야 함 (변명의 여지가 없음).
특히 요엘은 이렇게 말합니다.
인코딩에 대한 가장 중요한 단일 사실
방금 설명한 모든 것을 완전히 잊어 버린 경우 매우 중요한 사실 하나를 기억하십시오. 어떤 인코딩을 사용하는지 알지 못한 채 문자열을 갖는 것은 이치에 맞지 않습니다. 더 이상 머리를 모래에 붙이지 않고 "일반"텍스트를 ASCII로 가장 할 수 있습니다. 그러한 것은 일반 텍스트로 존재하지 않습니다.
문자열, 메모리, 파일 또는 전자 메일 메시지가있는 경우 해당 인코딩이 무엇인지 알거나 해석하거나 사용자에게 올바르게 표시 할 수 없습니다.
비 UTF 인코딩 (즉, BOM 없음)을 검색하려는 경우 기본적으로 텍스트의 휴리스틱 및 통계 분석을 수행합니다. 당신은 당신의유니버설 문자셋 탐지에 대한 Mozilla 논문(Wayback Machine을 통한 더 나은 서식 지정을 통한 동일한 링크).
시도해 봤어?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.");
}
}
}
private Encoding GetEncodingFromString(string encoding) { try { return Encoding.GetEncoding(encoding); } catch { return Encoding.ASCII; } }
- PrivatePyle
코드 페이지를 감지 할 수 없습니다.
이것은 분명히 거짓입니다. 모든 웹 브라우저에는 인코딩과 관련이 전혀없는 페이지를 처리 할 수있는 범용 문자 집합 감지기가 있습니다. Firefox에는 하나가 있습니다. 코드를 다운로드하고 코드를 확인하십시오. 몇 가지 문서보기이리. 기본적으로, 그것은 휴리스틱이지만, 실제로 잘 작동합니다.
합리적인 양의 텍스트가 주어지면 언어를 탐지 할 수도 있습니다.
또 하나가있다.방금 Google을 사용하여 찾았습니다.
a character encoding declaration is required even if the encoding is US-ASCII
- 부족한 선언은 UTF8로 돌아가는 것이 아니라 휴리스틱 알고리즘을 사용합니다. - z80crew
나는이 질문에 대해 매우 늦다는 것을 알고 있으며,이 솔루션은 영어 중심의 편견과 통계 / 경험적 테스트의 부재로 인해 어떤 사람들에게 호소력을 발휘하지 못할 것이다. 그러나 특히 업로드 된 CSV 데이터를 처리하는 데 매우 효과적이다.
http://www.architectshack.com/TextFileEncodingDetector.ashx
장점 :
참고 : 나는이 수업을 쓴 사람이므로 분명히 소금 한 알씩 가져 가라. :)
다른 해결책을 찾고, 나는 그것을 발견했다.
https://code.google.com/p/ude/
이 솔루션은 다소 무겁습니다.
4 바이트의 첫 번째 바이트와 아마도 XML charset 감지를 기반으로 기본적인 인코딩 감지가 필요했습니다. 그래서 인터넷에서 샘플 소스 코드를 가져 와서 약간 수정 된 버전을 추가했습니다.
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 바이트는 읽는 것으로 충분하지만 전체 파일을로드하고 있습니다.
누군가가 93.9 %의 해결책을 찾고 있다면. 이것은 나를 위해 작동합니다 :
public static class StreamExtension
{
/// <summary>
/// Convert the content to a string.
/// </summary>
/// <param name="stream">The stream.</param>
/// <returns></returns>
public static string ReadAsString(this Stream stream)
{
var startPosition = stream.Position;
try
{
// 1. Check for a BOM
// 2. or try with UTF-8. The most (86.3%) used encoding. Visit: http://w3techs.com/technologies/overview/character_encoding/all/
var streamReader = new StreamReader(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true), detectEncodingFromByteOrderMarks: true);
return streamReader.ReadToEnd();
}
catch (DecoderFallbackException ex)
{
stream.Position = startPosition;
// 3. The second most (6.7%) used encoding is ISO-8859-1. So use Windows-1252 (0.9%, also know as ANSI), which is a superset of ISO-8859-1.
var streamReader = new StreamReader(stream, Encoding.GetEncoding(1252));
return streamReader.ReadToEnd();
}
}
}
나는 파이썬에서 비슷한 것을했다. 기본적으로 다양한 인코딩의 샘플 데이터가 필요합니다.이 샘플 데이터는 슬라이딩 2 바이트 창으로 분해되고 사전 (해시)에 저장되며 인코딩 목록에 값을 제공하는 바이트 쌍으로 입력됩니다.
해당 사전 (해시)을 감안할 때 입력 텍스트를 가져 와서 다음을 수행하십시오.
UTF로 인코딩 된 텍스트도 샘플링 한 경우아니BOM으로 시작하면 두 번째 단계는 첫 번째 단계에서 미끄러 진 것을 처리합니다.
지금까지는 오류율이 줄어들어 샘플 데이터와 후속 입력 데이터가 다양한 언어의 자막으로 작동합니다.
도구 "uchardet"은 각 문자 집합에 대한 문자 빈도 분포 모델을 사용하여이를 잘 수행합니다. 더 큰 파일과 더 많은 "전형적인"파일은 더 많은 확신을 가지고 있습니다 (분명히).
우분투에서, 당신은 단지apt-get install uchardet
.
다른 시스템에서는 소스, 사용법 & docs here :https://github.com/BYVoid/uchardet
brew install uchardet
- Paul B
C 라이브러리에 링크 할 수 있으면 다음을 사용할 수 있습니다.libenca
. 만나다http://cihar.com/software/enca/. man 페이지에서 :
Enca는 주어진 텍스트 파일을 읽지 않거나 표준 입력이 없으면 읽습니다. 해당 언어에 대한 지식을 사용합니다 (귀하가 지원해야 함). 파싱, 통계 분석, 추측 및 흑 마법의 혼합 인코딩을 결정합니다.
그것은 GPL v2입니다.
동일한 문제가 있었지만 자동으로 감지 할 수있는 좋은 해결책을 찾지 못했습니다. 지금 PsPad (www.pspad.com)를 사용하고 있습니다.) 잘 작동합니다.
기본적으로 휴리스틱 스 (heuristics)로 내려 가기 때문에 이전에받은 파일의 인코딩을 첫 번째 힌트와 동일한 소스에서 사용하는 것이 도움이 될 수 있습니다.
대부분의 사람들 (또는 응용 프로그램)은 매번 같은 순서로 매번 같은 순서로 물건을 처리하기 때문에 Bob이 .csv 파일을 만들어 Mary에게 보냈을 때 Windows-1252 또는 그의 기계가 무엇이던간에.
가능하다면 고객 교육을 조금도 해칠 수는 없습니다 :-)
나는 실제로 파일 인코딩을 탐지하는 프로그래밍 방식이 아닌 일반적인 것을 찾고 있었지만, 아직 찾지 못했습니다. 다른 인코딩을 사용하여 테스트 한 결과 내 텍스트는 UTF-7이었습니다.
그래서 내가 처음 일을하는 곳 : StreamReader 파일 = File.OpenText (fullfilename);
나는 그것을 다음과 같이 변경해야했다 : StreamReader 파일 = 새 StreamReader (fullfilename, System.Text.Encoding.UTF7);
OpenText는 UTF-8이라고 가정합니다.
당신은 또한 이와 같은 StreamReader를 만들 수 있습니다. new StreamReader (fullfilename, true), 두 번째 매개 변수는 파일의 바이트 표시에서 인코딩을 검색해야하지만 내 경우에는 작동하지 않는다는 것을 의미합니다.
AkelPad에서 파일 열기 (또는 왜곡 된 텍스트 복사 / 붙여 넣기), 편집 -> 선택 -> 레코딩 ... -> "자동 검색"을 선택하십시오.
ITmeze 포스트의 addon으로,이 함수를 사용하여 Mozilla Universal Charset Detector의 C #포트 출력을 변환했습니다.
private Encoding GetEncodingFromString(string codePageName)
{
try
{
return Encoding.GetEncoding(codePageName);
}
catch
{
return Encoding.ASCII;
}
}
감사 @에릭 애런 스티언급uchardet
.
한편 (같은?) 도구가 리눅스에 존재합니다 :chardet
.
또는 cygwin에서 다음과 같이 사용할 수 있습니다 :chardetect
.
만나다:chardet man 페이지 :https://www.commandlinux.com/man-page/man1/chardetect.1.html
이렇게하면 주어진 파일마다 경험적으로 문자 인코딩을 추측 (추측)하고 각 파일에서 감지 된 문자 인코딩의 이름과 신뢰 수준을보고합니다.
이 질문 이후 10Y (!)가 지나갔고 여전히 MS의 좋은 GPL 솔루션에 대한 언급이 없습니다.국제어 2API.
이미 언급 된 대부분의 라이브러리는 모질라의 UDE를 기반으로하고 있습니다. 브라우저가 이미 비슷한 문제를 다루고있는 것은 합리적입니다. 나는 크롬의 해결책이 무엇인지 모르지만, IE 5.0 MS가 그것들을 발표 한 이래로 그것은 :
네이티브 COM 호출이지만여기에 아주 좋은 작품이있다.Carsten Zeumer가 .net 사용을위한 interop mess을 처리합니다. 주변에 다른 사람들이 있지만,이 도서관은 가치가있는 주목을받지 못합니다.
파일을 읽을 때이 코드를 사용하여 유니 코드 및 Windows 기본 ANSI 코드 페이지를 감지합니다. 다른 코드 작성의 경우 내용을 수동 또는 프로그래밍을 통해 확인해야합니다. 텍스트를 열 때와 동일한 인코딩으로 텍스트를 저장하는 데 사용할 수 있습니다. (나는 VB.NET을 사용한다)
'Works for Default and unicode (auto detect)
Dim mystreamreader As New StreamReader(LocalFileName, Encoding.Default)
MyEditTextBox.Text = mystreamreader.ReadToEnd()
Debug.Print(mystreamreader.CurrentEncoding.CodePage) 'Autodetected encoding
mystreamreader.Close()