먼저 독자가 인코딩이나 BOM에 익숙하지 않다면 먼저 .NET(C#): 문자 인코딩(Encoding) 및 바이트 순서 표시(BOM) 문서를 읽어 보는 것이 좋습니다.
중국어 코딩은 기본적으로 두 가지 범주로 나눌 수 있습니다.
1. ANSI 코딩의 확장 세트: GBK, GB2312, GB18030 등과 같은 코딩 유형에는 BOM이 없습니다(일부 최신 표준 중국어 코딩). , GB18030 및 GBK 인코딩과 같은 모든 기능은 GB2312 인코딩과 역호환됩니다.
2. 유니코드 인코딩 세트: UTF-8, UTF-16, UTF-32 등 이러한 유형의 코딩에는 BOM이 있을 수도 있고 없을 수도 있습니다.
3. 일부 유니코드 인코딩에는 소위 Little endian 및 Big endian이라는 특정 바이트 순서 문제(Endianess)도 있습니다. 다른 섹션 순서는 UTF16과 같이 다른 BOM에 해당하지만 UTF8에는 바이트 순서 문제가 없습니다. .
자, 기본 지식을 이해한 후 중국어 텍스트 파일을 올바르게 여는 방법에 대한 주제로 돌아가겠습니다. 확인해야 할 첫 번째 정보는 다음과 같습니다. 유니코드로 인코딩된 파일에 BOM이 포함되어 있습니까?
BOM까지 포함하면 뭐든지 말이 쉽죠! BOM을 찾으면 특정 인코딩을 알 수 있기 때문입니다. BOM을 찾을 수 없으면 유니코드가 아닙니다. 시스템의 기본 ANSI 확장 중국어 인코딩 세트를 사용하여 텍스트 파일을 열면 문제가 없습니다.
그리고 유니코드 인코딩에 BOM이 없는 경우(당연히 사용자가 제공한 모든 유니코드 파일에 BOM이 있다고 보장할 수는 없음) 원래 바이트에서 GBK인지 수동으로 확인해야 합니까? 아니면 UTF8? 아니면 다른 인코딩? . 이를 위해서는 특정 인코딩 감지 알고리즘이 필요합니다(구글에서 "charset|encoding 감지"를 검색할 수 있음). 물론 인코딩 감지 알고리즘이 100% 정확하지 않을 수도 있습니다. 바로 이 때문에 Windows 메모장에서 Bush는 사실 버그를 숨겼습니다. Chrome에서 웹을 탐색할 때 문자가 깨져 있는 경우도 있습니다. 개인적으로 Notepad++의 코딩 인식은 상당히 정확하다고 생각합니다.
다음 프로젝트와 같은 많은 코딩 인식 알고리즘이 있습니다: https://code.google.com/p/ude
유니코드가 BOM과 함께 제공되는 경우 세 번째- 파티 도서관. 그러나 설명해야 할 몇 가지 사항이 있습니다.
문제는 .NET의 텍스트 읽기 방법(File 클래스 및 StreamReader)이 기본적으로 UTF8 인코딩으로 읽기 때문에 이러한 GBK 텍스트 파일은 .NET으로 직접 열립니다(인코딩이 지정되지 않은 경우). 횡설수설해야 해!
우선 여기서 가장 효과적인 해결책은 시스템의 기본 비 유니코드 인코딩인 시스템의 기본 ANSI 확장 인코딩을 사용하여 텍스트를 읽는 것입니다. 참조 코드:
//输出系统默认非Unicode编码Console.WriteLine(Encoding.Default.EncodingName);//使用系统默认非Unicode编码来打开文件var fileContent = File.ReadAllText("C:\test.txt", Encoding.Default);
(간체) 중국어 Windows 시스템은 다음을 출력해야 합니다.
중국어 간체(GB2312)<텍스트 내용 생략>...
그리고 이 방법을 사용하는 것은 중국어 간체에만 국한되지 않습니다.
물론 GBK 인코딩과 같은 인코딩을 수동으로 지정할 수도 있습니다. 하지만 지정된 GBK 인코딩을 사용하여 유니코드 파일을 열면 파일이 성공적으로 열리나요? 대답은 여전히 성공적입니다. 그 이유는 .NET이 파일을 열 때 기본적으로 BOM을 자동으로 감지하고 BOM을 기반으로 얻은 인코딩을 사용하여 파일을 열기 때문입니다. BOM이 없으면 사용자가 지정한 인코딩 영역으로 파일이 열립니다. . 사용자가 인코딩을 지정하지 않으면 UTF8 인코딩이 사용됩니다.
이 "BOM 자동 인식" 매개변수는 detectorEncodingFromByteOrderMarks 매개변수에 해당하는 StreamReader 생성자에서 설정할 수 있습니다.
단, File 클래스의 해당 메소드에서는 설정할 수 없습니다. (예: File.ReadAllText)
예를 들어 다음 코드는 다음을 사용합니다.
GB2312 인코딩, BOM을 자동으로 감지하여 GB2312 텍스트 읽기
GB2312 인코딩, BOM을 자동으로 감지하여 유니코드 텍스트 읽기
GB2312 인코딩, BOM 인식 없이 유니코드 텍스트 읽기
static void Main(){ var gb2312 = Encoding.GetEncoding("GB2312"); //用GB2312编码,自动觉察BOM 来读取GB2312文本 ReadFile("gbk.txt", gb2312, true); //用GB2312编码,自动觉察BOM 来读取Unicode文本 ReadFile("unicode.txt", gb2312, true); //用GB2312编码,不觉察BOM 来读取Unicode文本 ReadFile("unicode.txt", gb2312, false);}//通过StreamReader读取文本 static void ReadFile(string path, Encoding enc, bool detectEncodingFromByteOrderMarks){ StreamReader sr; using (sr = new StreamReader(path, enc, detectEncodingFromByteOrderMarks)) { Console.WriteLine(sr.ReadToEnd()); }}
출력:
a刘a刘???
세 번째 줄이 깨졌습니다.
위에서 볼 수 있듯이 GB2312 인코딩을 사용하여 유니코드 파일을 여는 것도 성공합니다. "자동으로 BOM 검색" 매개 변수가 True이므로 파일에 BOM이 있는 것으로 확인되면 .NET에서는 BOM을 통해 해당 파일이 유니코드 파일임을 감지한 다음 유니코드를 사용하여 파일을 엽니다. 물론 BOM이 없으면 지정된 인코딩 매개변수를 사용하여 파일을 엽니다. GB2312로 인코딩된 텍스트의 경우 분명히 BOM이 없으므로 GB2312 인코딩을 지정해야 합니다. 그렇지 않으면 .NET에서는 기본 UTF8 인코딩을 사용하여 파일을 구문 분석하고 결과를 읽지 않습니다. 세 번째 줄의 잘못된 문자는 "BOM 자동 감지"가 False이기 때문입니다. .NET은 지정된 GB2312 인코딩을 직접 사용하여 BOM이 포함된 유니코드로 인코딩된 텍스트 파일을 읽습니다. 이는 분명히 성공할 수 없습니다.
물론 BOM을 직접 결정할 수도 있습니다. BOM이 없으면 텍스트를 열 때 기본 인코딩을 지정하세요. 이에 대해서는 이전 기사(.NET(C#): 파일에서 인코딩 감지)에서 썼습니다.
코드:
static void Main(){ PrintText("gb2312.txt"); PrintText("unicode.txt");}//根据文件自动觉察编码并输出内容static void PrintText(string path){ var enc = GetEncoding(path, Encoding.GetEncoding("GB2312")); using (var sr = new StreamReader(path, enc)) { Console.WriteLine(sr.ReadToEnd()); }}/// <summary>/// 根据文件尝试返回字符编码/// </summary>/// <param name="file">文件路径</param>/// <param name="defEnc">没有BOM返回的默认编码</param>/// <returns>如果文件无法读取,返回null。否则,返回根据BOM判断的编码或者缺省编码(没有BOM)。</returns>static Encoding GetEncoding(string file, Encoding defEnc){ using (var stream = File.OpenRead(file)) { //判断流可读? if (!stream.CanRead) return null; //字节数组存储BOM var bom = new byte[4]; //实际读入的长度 int readc; readc = stream.Read(bom, 0, 4); if (readc >= 2) { if (readc >= 4) { //UTF32,Big-Endian if (CheckBytes(bom, 4, 0x00, 0x00, 0xFE, 0xFF)) return new UTF32Encoding(true, true); //UTF32,Little-Endian if (CheckBytes(bom, 4, 0xFF, 0xFE, 0x00, 0x00)) return new UTF32Encoding(false, true); } //UTF8 if (readc >= 3 && CheckBytes(bom, 3, 0xEF, 0xBB, 0xBF)) return new UTF8Encoding(true); //UTF16,Big-Endian if (CheckBytes(bom, 2, 0xFE, 0xFF)) return new UnicodeEncoding(true, true); //UTF16,Little-Endian if (CheckBytes(bom, 2, 0xFF, 0xFE)) return new UnicodeEncoding(false, true); } return defEnc; }}//辅助函数,判断字节中的值static bool CheckBytes(byte[] bytes, int count, params int[] values){ for (int i = 0; i < count; i++) if (bytes[i] != values[i]) return false; return true;}
위 코드에서 유니코드 텍스트의 경우 GetEncoding 메서드는 UTF16 인코딩을 반환합니다. 더 구체적으로 말하면 BOM에 따라 Big 또는 Little-Endian UTF16 인코딩도 반환합니다. , BOM 없음 파일은 GB2312 인코딩 기본값을 반환합니다.
관련 게시물:
.NET(C#): 파일에서 인코딩 감지
.NET(C#): 문자 인코딩(Encoding) 및 바이트 순서 표시(BOM) )
.NET(C#): System.Text.Decoder 클래스를 사용하여 "스트림 텍스트" 처리
.NET(C#): 어셈블리 매니페스트 리소스 및 RESX 리소스에 대한 간략한 설명
위 내용은 .NET(C#)에서 중국어로 인코딩된 파일을 올바르게 읽는 방법에 대한 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!