Заставить C # использовать ASCII - PullRequest
5 голосов
/ 18 сентября 2009

Я работаю над приложением в C # и мне нужно читать и писать из определенного формата файла данных. Единственная проблема на данный момент состоит в том, что формат использует строго однобайтовые символы, и C # продолжает пытаться добавить Unicode, когда я использую записывающее устройство и массив char (который удваивает размер файла, среди других серьезных проблем). Я работал над модификацией кода, чтобы вместо этого использовать байтовые массивы, но это вызывает несколько жалоб при подаче их в древовидное представление и элементы управления сеткой данных, и это включает преобразования и тому подобное.

Я потратил немного времени на поиск в Google, и, похоже, не существует простой typedef, который я мог бы использовать, чтобы заставить тип char использовать байт для моей программы, по крайней мере, не вызывая дополнительных сложностей.

Есть ли простой способ заставить программу на C # .NET использовать только ASCII и не трогать Unicode?

Позже у меня это почти заработало. Использование ASCIIEncoding в BinaryReader / Writers привело к устранению большинства проблем (возникли некоторые проблемы с добавлением дополнительного символа к строкам, но я исправил это). У меня есть одна последняя проблема, которая очень мала, но может быть большой: в файле определенный символ (печатается как знак евро) преобразуется в ? при загрузке / сохранении файлов. Это не проблема в текстах, но если бы это происходило с рекордной длиной, он мог бы изменить размер на килобайт (очевидно, не очень). Я думаю, что это вызвано кодировкой, но если оно пришло из файла, почему оно не вернулось назад?

Точная проблема / результаты таковы:

  • Оригинальный файл: 0x80 (евро)

  • Кодировка: ** ASCII: 0x3F (?) ** UTF8: 0xC280 (евро-шляпа)

Ни один из этих результатов не будет работать, поскольку в любом месте файла он может измениться (если 80 изменится на 3F при длине записи int, это может быть разница 65 * (256 ^ 3)). Нехорошо. Я попытался использовать кодировку UTF-8 , полагая, что это очень хорошо решит проблему, но теперь добавляется второй символ, что еще хуже.

Ответы [ 4 ]

24 голосов
/ 18 сентября 2009

C # (.NET) всегда будет использовать Юникод для строк. Это по замыслу.

Когда вы читаете или пишете в свой файл, вы можете, однако, использовать StreamReader / StreamWriter, установленный для принудительного кодирования ASCII, например:

StreamReader reader = new StreamReader (fileStream, new ASCIIEncoding());

Тогда просто прочитайте с помощью StreamReader.

Запись одинакова, просто используйте StreamWriter.

5 голосов
/ 18 сентября 2009

Интегральные строки в .NET всегда являются Unicode, но это не должно вас интересовать. Если у вас есть определенный формат, который вы должны придерживаться, то маршрут, по которому вы пошли (считая его как байты), был правильным. Вам просто нужно использовать класс System.Encoding.ASCII для конвертации из string->byte[] и byte[]->string.

3 голосов
/ 16 января 2010

Если у вас есть формат файла, который смешивает текст в однобайтовых символах с двоичными значениями, такими как длина, управляющие символы, хорошей кодировкой для использования является кодовая страница 28591, также известная как Latin1 или ISO-8859-1.

Вы можете получить эту кодировку, используя любое из следующих значений:

Encoding.GetEncoding(28591) 
Encoding.GetEncoding("Latin1")
Encoding.GetEncoding("ISO-8859-1")

Эта кодировка имеет полезную характеристику, заключающуюся в том, что значения байтов до 255 преобразуются в неизмененные значения в символ Unicode с тем же значением (например, байт 0x80 становится символом 0x0080).

В вашем сценарии это может быть более полезным, чем кодировка ASCII (которая преобразует значения в диапазоне от 0x80 до 0xFF в '?') Или любые другие обычные кодировки, которые также преобразуют некоторые символы в этом диапазоне .

0 голосов
/ 20 сентября 2009

Если вы хотите это в .NET , вы можете использовать F # для создания библиотеки, поддерживающей это. F # поддерживает строки ASCII, с байтовым массивом в качестве основного типа, см. Литералы (F #) (MSDN):

let asciiString = "This is a string"B
...