C #: есть ли способ узнать, какую кодировку использует файл?
Есть ли способ узнать, какую кодировку использует файл?
7 ответов
Единственный способ сделать это надежно — найти метки порядка байтов в начале текстовый файл. (Этот blob в более общем смысле представляет собой порядок байтов используемой кодировки символов, но также и кодировку — например, UTF8, UTF16, UTF32). К сожалению, этот метод работает только для кодировок на основе Unicode и ничего до этого (для которых необходимо использовать гораздо менее надежные методы).
Тип StreamReader поддерживает обнаружение этих метки для определения кодировки — вам просто нужно передать флаг параметру как таковой:
Затем вы можете проверить значение stremReader.CurrentEncoding , чтобы определить кодировку, используемую файлом. Однако обратите внимание, что если метки байтовой кодировки не существуют, то CurrentEncoding по умолчанию будет Encoding.Default .
Нет отличного способа обнаружить произвольную кодовую страницу ANSI, хотя были попытки сделать это, основываясь на вероятности наличия определенных последовательностей байтов в середине текста. Мы не пытаемся этого сделать в StreamReader. Некоторые форматы файлов, такие как XML или HTML, позволяют указать набор символов в первой строке файла, чтобы веб-браузеры, базы данных и классы, такие как XmlTextReader, могли правильно читать эти файлы. Но многие текстовые файлы не содержат такой информации.
Невозможно сделать это со 100% надежностью. Вы должны решить, какой компромисс между стоимостью и точностью вам удобен. В этом ответе я обсуждаю многие возможные алгоритмы (с плюсами и минусами): Сценарий поиска PowerShell, игнорирующий двоичные файлы
Как указал Ричард, полностью надежного способа сделать это нет. Однако вот несколько потенциально полезных ссылок:
Некоторое время назад я написал это на C ++, и это стало довольно сложно. Вот что я делаю (принимаю первое, что подходит):
- Найдите метки порядка байтов
- Проверить правильность текста UTF-32 BE / LE
- Проверьте правильность текста UTF-16 BE / LE
- Проверьте правильность текста UTF-8
- Предположить текущую кодовую страницу
Это справляется со многими текстовыми файлами без спецификации, но не помогает с текстом, хранящимся с пользовательскими кодовыми страницами ANSI.
Для них невозможно детерминированное обнаружение. Например. файл, сохраненный с кодировкой «восточноевропейская» и загружаемый на компьютер с кодовой страницей по умолчанию «западноевропейская», будет искажен.
Единственная возможность помочь в этом случае — позволить пользователю выбрать кодовую страницу (с точки зрения пользователя лучше всего было бы позволить пользователю изменить предполагаемую кодировку, когда он увидит текст).
Он работает нормально на тестовом наборе, но, конечно, возможны неправильные интерпретации, если они маловероятны.
Кодовые страницы могут быть определены путем статистического анализа текста (например, частота пар и троек символов, содержащих символы, отличные от ASCII, или списки слов на разных языках, но я не нашел подходящего подхода для этого.
IsTextUnicode в Win32 заведомо плохой, он проверяет только для UTF-16 и, вероятно, является виновником того, что «куст спрятал факты» в блокноте.
Как определить кодировку символов текстового файла?
Я пытаюсь определить, какая кодировка символов используется в моем файле.
Я пытаюсь с этим кодом получить стандартное кодирование
Мой пять первых байтов — 60, 118, 56, 46 и 49.
Есть ли диаграмма, которая показывает, какая кодировка соответствует этим пяти первым байтам?
8 ответов
Вы не можете зависеть от файла, имеющего спецификацию. UTF-8 не требует этого. И кодировки, отличные от Unicode, даже не имеют спецификации. Существуют, однако, другие способы обнаружения кодирования.
UTF-32
BOM — 00 00 FE FF (для BE) или FF FE 00 00 (для LE).
Но UTF-32 легко обнаружить даже без спецификации. Это связано с тем, что диапазон кодовой точки Юникода ограничен U + 10FFFF, и, таким образом, единицы UTF-32 всегда имеют шаблон 00 <0x | 10>xx xx (для BE) или xx xx <0x | 10>00 (для LE), Если данные имеют длину, кратную 4, и следуют одному из этих шаблонов, вы можете смело предположить, что это UTF-32. Ложные срабатывания почти невозможны из-за редкости 00 байтов в байтовом кодировании.
US-ASCII
Нет спецификации, но вам она не нужна. ASCII можно легко идентифицировать по отсутствию байтов в диапазоне 80 FF.
BOM — EF BB BF. Но вы не можете полагаться на это. Многие файлы UTF-8 не имеют спецификации, особенно если они возникли в системах, отличных от Windows.
Но вы можете смело предположить, что если файл проверяется как 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 находится в начале спецификации UTF-32LE, поэтому сначала проверьте UTF-32.
Могут быть файлы UTF-16 без спецификации, но было бы очень сложно их обнаружить. Единственный надежный способ распознавания UTF-16 без спецификации — искать суррогатные пары (D [8-B] xx D [CF] xx), но символы, отличные от BMP, слишком редко используются, чтобы сделать этот подход практичным.
Если ваш файл начинается с байтов 3C 3F 78 6D 6C (то есть символов ASCII «<? xml» ), тогда найдите объявление encoding= . Если присутствует, используйте эту кодировку. Если отсутствует, то предположим, что UTF-8, который является стандартным XML-кодированием.
Если вам необходимо поддерживать EBCDIC, также ищите эквивалентную последовательность 4C 6F A7 94 93.
В общем случае, если у вас есть формат файла, который содержит объявление кодировки, тогда найдите это объявление, а не пытайтесь угадать кодировку.
Ничего из вышеперечисленного
Существуют сотни других кодировок, которые требуют больше усилий для обнаружения. Я рекомендую попробовать детектор charset Mozilla или порт .NET.
How to detect the character encoding of a text file in C#?
Detecting the character encoding of a text file is a common task in programming, particularly when working with a large number of files. This is because text files can be encoded in a variety of ways, including ASCII, UTF-8, UTF-16, and others. Knowing the encoding of a text file is important because it allows you to properly read and interpret the file's contents. In this article, we will discuss several methods to detect the character encoding of a text file using C#.
Method 1: Using the System.Text.Encoding class
To detect the character encoding of a text file in C# using the System.Text.Encoding class, you can follow these steps:
- Read the text file into a byte array using the File.ReadAllBytes method.
- Create an instance of the Encoding class by calling the Encoding.GetEncoding method and passing in the byte array.
- Convert the byte array to a string using the Encoding.GetString method.
- Check the Encoding.EncodingName property to get the name of the encoding used in the text file.
Here is the complete code example:
Note: In the Encoding.GetEncoding method, you can pass in the name of the encoding used in the text file as the first argument. If you don't know the encoding name, you can pass in null or string.Empty and the method will try to automatically detect the encoding.
Method 2: Using the System.IO.FileStream class
To detect the character encoding of a text file in C# using the System.IO.FileStream class, you can follow these steps:
- Create a new instance of the FileStream class, passing the path to the file and the FileMode.Open parameter to open the file in read-only mode.
- Create a new instance of the StreamReader class, passing the fileStream object and true for the detectEncodingFromByteOrderMarks parameter to automatically detect the encoding based on the byte order marks at the beginning of the file.
- Get the detected encoding by accessing the CurrentEncoding property of the StreamReader object.
- Close the StreamReader and FileStream objects to release the resources.
Here is the complete code example:
Note that this method may not always be accurate, as some files may not have byte order marks or may have an ambiguous encoding. In those cases, you may need to use other methods, such as manually checking for specific byte sequences or using third-party libraries.
Method 3: Using the Microsoft.VisualBasic.FileIO.TextFieldParser class
To detect the character encoding of a text file in C# using the Microsoft.VisualBasic.FileIO.TextFieldParser class, you can follow these steps:
- Create an instance of the TextFieldParser class, passing the path of the text file as a parameter.
- Set the TextFieldType property of the TextFieldParser instance to FieldType.Delimited .
- Set the Delimiters property of the TextFieldParser instance to an array containing the characters you want to use as delimiters (e.g. new string[] < "," >).
- Call the ReadFields method of the TextFieldParser instance to read the first line of the text file.
- Use the Encoding property of the TextFieldParser instance to get the detected encoding of the text file.
Here is an example code snippet that demonstrates this approach:
In this example, we assume that the text file is delimited by commas. You can adjust the Delimiters property to match the actual delimiters used in your text file.
Note that the TextFieldParser class is part of the Microsoft.VisualBasic namespace, which means that you need to add a reference to the Microsoft.VisualBasic.dll assembly in your project to use it.
Method 4: Using third-party libraries such as ICU
To detect the character encoding of a text file in C# using third-party libraries such as ICU, you can follow these steps:
Install the ICU package from NuGet by running the following command in the Package Manager Console:
Import the necessary namespaces:
Read the contents of the text file into a byte array:
Create an instance of the CharsetDetector class:
Set the input byte array:
Invoke the Detect method to detect the character encoding:
Get the name of the detected character encoding:
Here's the complete code:
This code will detect the character encoding of the text file and store the name of the encoding in the encodingName variable.
Получить кодировку текстового файла
Получить строку из текстового файла на сайте
нужно вывести например из http://йцуйцуйцу.net/version.txt там всего 1 строка и мне её надо.
Получить все строки текстового файла f1 и вывести их в файл f2 и на экран
Дан текстовый файл f1. Получить все его строки, содержащие более 60 символов. Вывести их в файл f2.
Из строк текстового файла получить имена файлов и записать их в отдельный текстовый файл
Доброго времени суток, имеется текстовый файл, порядка 7-ми или 8-ми тысяч строк.
Нужно получить кодировку HTML разметки
Нужно получить кодировку HTML разметки Получаю HTML разметку следующим образом WebClient client.
Кодировка Windows-1251
Или нужно получить кодировку текстового файла?
Добавлено через 7 минут
Теперь немного поясню: Сиволы в UTF-8 кодируются последовательностями длиной от 1 до 4 байт (октетов).
Вот в таком формате:
По маске первого октета определяется общее число октет в последовательности, а затем они проверяются на соответствие маске 10xxxxxx. Если какой-то байт не соответсвует маске, значит кодировка отличная от UTF-8 (в моем случае win1251).
Код, конечно, громоздкий, но для демонстрации самого алгоритма вполне достаточный.
Сообщение было отмечено как решение
Решение
Dark-VIN, расширение + анализ первых байтов файла. На сайте filext.com можно найти информацию о идентифицирующих байтах для интересующих тебя расширений.
Добавлено через 1 час 34 минуты
P.S. Несмотря на то что тема была создана в марте 2013 года стоит отметить что примеры кода приведенные BigOblom и IamRain содержат недочеты.
Пример из сообщения BigOblom проверяет BOM только для UTF-8, в то время еще как нужно проверять UTF-16, UTF-16 Big Endian и UTF-32. Также результат проверок сводится только к выбору между windows-1251 или UTF-8.
Пример IamRain нерабочий. StreamReader умеет определять только кодировки семейства Unicode (с помощью BOM), но свойство CurrentEncoding при этом всегда UTF-8. Остальные кодировки он вообще не умеет определять.
Если перед вами стоит задача определения кодировки текста, то советую использовать библиотеку Mozilla Universal Charset Detector.