Как преобразовать string
к byte[]
в .NET (C #), вручную указав конкретную кодировку?
Я собираюсь зашифровать строку. Я могу зашифровать его без конвертации, но я все же хотел бы знать, почему здесь играет роль кодировка.
Кроме того, почему кодирование должно быть принято во внимание? Разве я не могу просто получить, в каких байтах хранится строка? Почему существует зависимость от кодировки символов?
c#
.net
string
character-encoding
Агнель Курьян
источник
источник
Ответы:
Вопреки ответам здесь, вам не нужно беспокоиться о кодировании, если байты не нужно интерпретировать!
Как вы упомянули, ваша цель - просто «получить, в каких байтах хранится строка» .
(И, конечно же, чтобы можно было восстановить строку из байтов.)
Для этих целей я, честно говоря, не понимаю, почему люди продолжают говорить вам, что вам нужны кодировки. Вам, конечно, не нужно беспокоиться о кодировках для этого.
Просто сделайте это вместо этого:
До тех пор, пока ваша программа (или другие программы) не пытаются как-то интерпретировать байты, что вы явно не упомянули, что собираетесь делать, в этом нет ничего плохого! Беспокойство по поводу кодировок просто усложняет вашу жизнь без всякой реальной причины.
Дополнительное преимущество этого подхода:
Не имеет значения, содержит ли строка недопустимые символы, потому что вы все равно можете получить данные и восстановить исходную строку!
Он будет закодирован и декодирован точно так же, потому что вы просто смотрите на байты .
Однако, если бы вы использовали определенную кодировку, это привело бы к проблемам с кодированием / декодированием недопустимых символов.
источник
GetString
иGetBytes
нужно выполняться на системе с одной и той же работы на порядок байтов. Таким образом, вы не можете использовать это, чтобы получить байты, которые вы хотите превратить в строку в другом месте. Поэтому мне трудно придумывать ситуации, в которых я хотел бы использовать это.Это зависит от кодировки вашей строки ( ASCII , UTF-8 , ...).
Например:
Небольшой пример, почему кодирование имеет значение:
ASCII просто не оборудован для работы со специальными символами.
Внутри .NET Framework использует UTF-16 для представления строк, поэтому, если вы просто хотите получить точные байты, которые использует .NET, используйте
System.Text.Encoding.Unicode.GetBytes (...)
.См. Кодировка символов в .NET Framework (MSDN) для получения дополнительной информации.
источник
Принятый ответ очень, очень сложный. Используйте для этого включенные классы .NET:
Не изобретайте велосипед, если вам не нужно ...
источник
System.Text.Encoding.Unicode
быть эквивалентна ответу Мерадада.System.Text.Encoding.Unicode.GetBytes
вероятно , было бы более точным.источник
Вы должны принять во внимание кодировку, потому что 1 символ может быть представлен 1 или более байтами (до 6), и разные кодировки будут обрабатывать эти байты по-разному.
У Джоэла есть пост на эту тему:
источник
Это популярный вопрос. Важно понимать, что задает автор вопроса, и что он отличается от того, что, вероятно, является наиболее распространенной потребностью. Чтобы воспрепятствовать неправильному использованию кода там, где он не нужен, я ответил первым позже.
Общая потребность
Каждая строка имеет набор символов и кодировку. Когда вы конвертируете
System.String
объект в массив, уSystem.Byte
вас все равно есть набор символов и кодировка. В большинстве случаев вы знаете, какой набор символов и кодировку вам нужны, а .NET упрощает «копирование с преобразованием». Просто выберите подходящийEncoding
класс.Преобразование может потребоваться для обработки случаев, когда целевой набор символов или кодировка не поддерживает символ, который находится в источнике. У вас есть несколько вариантов: исключение, замена или пропуск. Политика по умолчанию заменяет «?».
Очевидно, что конверсии не обязательно без потерь!
Примечание: для
System.String
исходного набора символов используется Unicode.Единственная путаница в том, что .NET использует имя набора символов для имени одной конкретной кодировки этого набора символов.
Encoding.Unicode
должен быть названEncoding.UTF16
.Вот и все для большинства случаев. Если это то, что вам нужно, перестаньте читать здесь. Посмотрите забавную статью Джоэла Спольски, если вы не понимаете, что такое кодировка.
Конкретная потребность
Теперь автор вопроса спрашивает: «Каждая строка хранится в виде массива байтов, верно? Почему я не могу просто иметь эти байты?»
Он не хочет никакого обращения.
Из спецификации C # :
Итак, мы знаем, что если мы запросим нулевое преобразование (то есть из UTF-16 в UTF-16), мы получим желаемый результат:
Но чтобы избежать упоминания о кодировках, мы должны сделать это по-другому. Если промежуточный тип данных приемлем, есть концептуальное сокращение для этого:
Это не дает нам желаемый тип данных, но ответ Мердада показывает, как преобразовать этот массив Char в байтовый массив с помощью BlockCopy . Тем не менее, это копирует строку дважды! И он слишком явно использует специфичный для кодирования код: тип данных
System.Char
.Единственный способ получить фактические байты, в которых хранится строка - это использовать указатель.
fixed
Заявление позволяет принимать адрес значений. Из спецификации C #:Для этого компилятор пишет код, пропускающий другие части строкового объекта с помощью
RuntimeHelpers.OffsetToStringData
. Итак, чтобы получить необработанные байты, просто создайте указатель на строку и скопируйте необходимое количество байтов.Как указал @CodesInChaos, результат зависит от порядкового номера машины. Но автора вопроса это не касается.
источник
Length
Свойство [ofString
] возвращает количествоChar
объектов в этом экземпляре, а не количество символов Юникода». Ваш пример кода, следовательно, правильно, как написано.new String(new []{'\uD800', '\u0030'})
Globalization.SortKey
, извлекатьKeyData
и упаковывать результирующие байты из каждого вString
[два байта на символ, сначала MSB ], вызовString.CompareOrdinal
результирующих строк будет существенно быстрее, чем вызовSortKey.Compare
экземпляровSortKey
, или даже призываяmemcmp
к этим случаям. Учитывая это, мне интересно, почемуKeyData
возвращается,Byte[]
а неString
?На первую часть вашего вопроса (как получить байты) уже отвечали другие: посмотрите в
System.Text.Encoding
пространство имен.Я отвечу на ваш следующий вопрос: зачем вам выбирать кодировку? Почему вы не можете получить это из самого строкового класса?
Ответ состоит из двух частей.
Прежде всего, байты, используемые внутренне классом string, не имеют значения , и всякий раз, когда вы предполагаете, что они это делают, вы, вероятно, вносите ошибку.
Если ваша программа полностью находится в мире .Net, вам не нужно беспокоиться о получении байтовых массивов для строк, даже если вы отправляете данные по сети. Вместо этого используйте .Net Serialization, чтобы беспокоиться о передаче данных. Вы больше не беспокоитесь о реальных байтах: средство форматирования Serialization сделает это за вас.
С другой стороны, что, если вы отправляете эти байты куда-то, что, как вы не можете гарантировать, извлечет данные из сериализованного потока .Net? В этом случае вам определенно нужно беспокоиться о кодировании, потому что, очевидно, эта внешняя система заботится. Итак, опять же, внутренние байты, используемые строкой, не имеют значения: вам нужно выбрать кодировку, чтобы вы могли четко указать эту кодировку на принимающей стороне, даже если это та же кодировка, которая используется внутри .Net.
Я понимаю, что в этом случае вы могли бы предпочесть использовать фактические байты, сохраненные строковой переменной в памяти, где это возможно, с идеей, что это может сэкономить некоторую работу, создавая ваш поток байтов. Тем не менее, я говорю вам, что это просто не важно по сравнению с тем, чтобы убедиться, что ваш вывод понят на другом конце, и гарантировать, что вы должны четко указывать свою кодировку. Кроме того, если вы действительно хотите сопоставить свои внутренние байты, вы уже можете просто выбрать
Unicode
кодировку и получить эту экономию производительности.Это подводит меня ко второй части ... выбирая
Unicode
кодирование является говорить .Net , чтобы использовать основные байты. Вам нужно выбрать эту кодировку, потому что, когда выходит какой-то новый Unicode-Plus, среда выполнения .Net должна быть свободна, чтобы использовать эту более новую, лучшую модель кодирования, не ломая вашу программу. Но на данный момент (и в обозримом будущем) простой выбор кодировки Unicode даст вам то, что вы хотите.Также важно понимать, что ваша строка должна быть перезаписана на провод, и это включает в себя, по крайней мере, некоторый перевод битового шаблона, даже если вы используете соответствующую кодировку . Компьютер должен учитывать такие вещи, как Big против Little Endian, порядок байтов в сети, пакетирование, информация о сеансе и т. Д.
источник
Просто чтобы показать , что звук Mehrdrad в ответ работает, его подход может даже сохраняться непарные символы суррогатных (многие из которых были направлены против моего ответа, но о которых все одинаково виновны, например
System.Text.Encoding.UTF8.GetBytes
,System.Text.Encoding.Unicode.GetBytes
а те методы кодирования не могут сохраняться высокий суррогатd800
например, символы , которые просто заменяют старшие суррогатные символы значениемfffd
):Вывод:
Попробуйте это с System.Text.Encoding.UTF8.GetBytes или System.Text.Encoding.Unicode.GetBytes , они просто заменят старшие суррогатные символы значением fffd
Каждый раз, когда в этом вопросе есть движение, я все еще думаю о сериализаторе (будь то от Microsoft или от стороннего компонента), который может сохранять строки, даже если он содержит непарные суррогатные символы; Я гуглю это время от времени: сериализация непарного суррогатного персонажа .NET . Это не заставляет меня терять сон, но это немного раздражает, когда время от времени кто-то комментирует мой ответ, что он ошибочен, но его ответы одинаково несовершенны, когда речь идет о непарных суррогатных персонажах.
Черт, Microsoft должна была просто использовать
System.Buffer.BlockCopy
в своемBinaryFormatter
ツ谢谢!
источник
System.Buffer.BlockCopy
внутренне, все аргументы сторонников кодирования будут спорнымиFFFD
в этом символе. Если вы хотите выполнять ручные манипуляции со строками, используйте char [] в соответствии с рекомендациями.System.String
является неизменной последовательностьюChar
; .NET всегда позволялString
конструировать объект из любогоChar[]
и экспортировать его содержимое в одно иChar[]
то же значение, даже если оригиналChar[]
содержит непарные суррогаты.Попробуйте это, намного меньше кода:
источник
System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép);
и плачь! Это будет работать, ноSystem.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép").Length != System.Text.Encoding.UTF8.GetBytes("Arvizturo tukorfurogep").Length
пока"Árvíztűrő tükörfúrógép".Length == "Arvizturo tukorfurogep".Length
Ну, я прочитал все ответы, и они были об использовании кодировки или о сериализации, которая отбрасывает непарные суррогаты.
Это плохо, когда строка, например, исходит от SQL Server где она была построена из байтового массива, например, хэша пароля. Если мы отбросим что-либо из него, он сохранит недопустимый хеш, а если мы хотим сохранить его в XML, мы хотим оставить его нетронутым (поскольку средство записи XML отбрасывает исключение для любого найденного непарного суррогата).
Поэтому в таких случаях я использую кодирование байтовых массивов Base64 , но, эй, в Интернете есть только одно решение этой проблемы в C #, в котором есть ошибка и есть только один способ, поэтому я исправил ошибку и переписал процедура. Вот вы, будущие гуглеры:
источник
Convert.ToBase64String(arr);
для преобразования base64byte[] (data) <-> string (serialized data to store in XML file)
. Но , чтобы получить первоначальныйbyte[] (data)
мне нужно сделать что - то сString
который содержал двоичные данные (это способ MSSQL вернул его мне). Так что функции выше дляString (binary data) <-> byte[] (easy accessible binary data)
.Потому что нет такой вещи как «байты строки».
Строка (или, в более общем смысле, текст) состоит из символов: букв, цифр и других символов. Это все. Компьютеры, однако, ничего не знают о персонажах; они могут обрабатывать только байты. Поэтому, если вы хотите сохранить или передать текст с помощью компьютера, вам необходимо преобразовать символы в байты. Как ты это делаешь? Вот где кодировки приходят на сцену.
Кодировка - это не что иное, как соглашение о переводе логических символов в физические байты. Самая простая и известная кодировка - ASCII, и это все, что вам нужно, если вы пишете на английском языке. Для других языков вам понадобятся более полные кодировки, так как любой из вариантов Unicode является самым безопасным выбором на сегодняшний день.
Короче говоря, попытка «получить байты строки без использования кодировок» так же невозможна, как «запись текста без использования какого-либо языка».
Кстати, я настоятельно рекомендую вам (и любому, в этом отношении) прочитать эту маленькую мудрость: Абсолютный минимум, который должен быть у каждого разработчика программного обеспечения. Абсолютно, положительно необходимо знать о Юникоде и наборах символов (никаких оправданий!)
источник
C # для преобразования
string
вbyte
массив:источник
источник
Вы можете использовать следующий код для преобразования между строкой и байтовым массивом.
источник
С появлением
Span<T>
выпущенного в C # 7.2 канонического метода для захвата основного представления памяти строки в массив управляемых байтов:Преобразование обратно должно быть непростым, потому что это означает, что вы на самом деле интерпретируете данные как-то, но ради полноты:
Имена
NonPortableCast
иDangerousGetPinnableReference
должны приводить аргумент, что вы, вероятно, не должны делать это.Обратите внимание, что работа с
Span<T>
требует установки пакета System.Memory NuGet .Несмотря на это, фактический исходный вопрос и последующие комментарии подразумевают, что базовая память не «интерпретируется» (что, я полагаю, означает, что она не изменена и не считана за исключением необходимости писать ее как есть), что указывает на некоторую реализацию
Stream
класса следует использовать вместо рассуждений о данных как о строках вообще.источник
Я не уверен, но я думаю, что строка хранит свою информацию в виде массива символов, что неэффективно с байтами. В частности, определение Char является «Представляет символ Unicode».
возьмите пример этого примера:
Обратите внимание, что ответ Unicode составляет 14 байтов в обоих случаях, тогда как ответ UTF-8 составляет только 9 байтов для первого и только 7 для второго.
Поэтому, если вы просто хотите, чтобы байты использовались строкой, просто используйте
Encoding.Unicode
, но это будет неэффективно с пространством хранения.источник
Ключевая проблема заключается в том, что глиф в строке занимает 32 бита (16 битов для кода символа), но для байта требуется только 8 бит. Сопоставление один к одному не существует, если вы не ограничиваете себя строками, которые содержат только символы ASCII. System.Text.Encoding имеет много способов сопоставить строку с byte [], вам нужно выбрать тот, который позволяет избежать потери информации и который легко использовать вашему клиенту, когда ему необходимо сопоставить byte [] со строкой ,
Utf8 - это популярная кодировка, она компактная и без потерь.
источник
Использование:
Результат:
источник
Самый быстрый способ
РЕДАКТИРОВАТЬ, как прокомментировал Макотосан, теперь это лучший способ:
источник
строка в .NET представляет текст в виде последовательности UTF-16 единиц коды, так что байты кодируются в памяти в UTF-16 уже.
Ответ Мердада
Вы можете использовать ответ Mehrdad , но он на самом деле использует кодировку, потому что символы UTF-16. Он вызывает ToCharArray, который, глядя на источник, создает
char[]
и напрямую копирует в него память. Затем он копирует данные в байтовый массив, который также выделяется. Таким образом, он скрывает два байта и выделяет массив символов, который не используется после вызова.Ответ Тома Блоджетта
Ответ Tom Blodget на 20-30% быстрее, чем Mehrdad, поскольку он пропускает промежуточный этап выделения массива char и копирования в него байтов, но требует компиляции с
/unsafe
опцией. Если вы абсолютно не хотите использовать кодирование, я думаю, что это путь. Если вы поместите свой логин шифрования внутриfixed
блока, вам даже не нужно выделять отдельный массив байтов и копировать в него байты.Потому что это правильный способ сделать это.
string
это абстракция.Использование кодировки может создать проблемы, если у вас есть «строки» с недопустимыми символами, но этого не должно происходить. Если вы вводите данные в строку с недопустимыми символами, вы делаете это неправильно. Для начала вам, вероятно, следует использовать байтовый массив или кодировку Base64.
Если вы используете
System.Text.Encoding.Unicode
, ваш код будет более устойчивым. Вам не нужно беспокоиться о порядке работы системы, в которой будет выполняться ваш код. Вам не нужно беспокоиться, если в следующей версии CLR будет использоваться другая внутренняя кодировка символов.Я думаю, вопрос не в том, почему вы хотите беспокоиться о кодировке, а в том, почему вы хотите игнорировать ее и использовать что-то еще. Кодирование предназначено для представления абстракции строки в последовательности байтов.
System.Text.Encoding.Unicode
даст вам немного порядковый порядок байтов и будет выполнять то же самое в каждой системе, сейчас и в будущем.источник
Наиболее близким подходом к вопросу ОП является вопрос Тома Блоджетта, который фактически входит в объект и извлекает байты. Я говорю ближе всего, потому что это зависит от реализации объекта String.
Конечно, но в этом и заключается принципиальная ошибка в этом вопросе. String - это объект, который может иметь интересную структуру данных. Мы уже знаем, что делает, потому что позволяет хранить непарные суррогаты. Это может хранить длину. Он может содержать указатель на каждый из «парных» суррогатов, позволяющих быстро считать. И т.д. Все эти дополнительные байты не являются частью символьных данных.
То, что вы хотите, это байты каждого символа в массиве. И тут начинается кодировка. По умолчанию вы получите UTF-16LE. Если вы не заботитесь о самих байтах, за исключением обратной передачи, тогда вы можете выбрать любую кодировку, включая 'default', и преобразовать ее позже (при условии, что будут те же параметры, что и кодировка по умолчанию, кодовые точки, исправления ошибок). разрешенные вещи, такие как непарные суррогаты и т. д.
Но зачем оставлять «кодирование» волшебным? Почему бы не указать кодировку, чтобы вы знали, какие байты вы собираетесь получить?
Кодировка (в этом контексте) просто означает байты, которые представляют вашу строку. Не байты строкового объекта. Вы хотели, чтобы байты, в которых была сохранена строка - вопрос был задан наивно. Вы хотели получить байты строки в непрерывном массиве, который представляет строку, а не все другие двоичные данные, которые может содержать строковый объект.
Что означает, как хранится строка, не имеет значения. Вы хотите строку «Encoded» в байтах в байтовом массиве.
Мне нравится ответ Тома Блога, потому что он направил вас к направлению «байты строкового объекта». Это зависит от реализации, и, поскольку он заглядывает во внутренности, может быть трудно воссоздать копию строки.
Реакция Мердада неверна, потому что вводит в заблуждение на концептуальном уровне. У вас еще есть список байтов, закодированный. Его конкретное решение позволяет сохранить непарные суррогаты - это зависит от реализации. Его конкретное решение не даст точные байты строки, если
GetBytes
по умолчанию возвращает строку в UTF-8.Я передумал об этом (решение Мехрдада) - это не получение байтов строки; скорее это получение байтов символьного массива, который был создан из строки. Независимо от кодировки тип данных char в c # имеет фиксированный размер. Это позволяет создавать байтовый массив одинаковой длины и воспроизводить массив символов в зависимости от размера байтового массива. Таким образом, если бы кодировкой было UTF-8, но каждый символ составлял 6 байтов для размещения наибольшего значения utf8, он все равно работал бы. Так и есть - кодировка символа не имеет значения.
Но было использовано преобразование - каждый символ был помещен в поле фиксированного размера (тип символа c #). Однако, что это за представление, не имеет значения, что технически является ответом на ФП. Так что - если вы все равно собираетесь конвертировать ... Почему бы не "кодировать"?
источник
&(Char) 55906
&(Char) 55655
. Так что вы можете ошибаться, и ответ Мехрдада - это безопасное преобразование без учета того, какой тип кодирования используется.Вы можете использовать следующий код для преобразования
string
кbyte array
в .NETисточник
Если вам действительно нужна копия нижележащих байтов строки, вы можете использовать функцию, подобную следующей. Тем не менее, вы не должны читать дальше, чтобы узнать, почему.
Эта функция довольно быстро даст вам копию байтов, лежащих в основе вашей строки. Вы получите эти байты любым способом, который они кодируют в вашей системе. Эта кодировка почти наверняка UTF-16LE, но это деталь реализации, о которой вам не нужно беспокоиться.
Было бы безопаснее, проще и надежнее просто позвонить,
По всей вероятности, это даст тот же результат, его легче набирать, а байты всегда будут возвращаться туда и обратно с вызовом
источник
Вот моя небезопасная реализация
String
дляByte[]
преобразования:Это намного быстрее, чем принятый ответ, даже если не так элегантно, как есть. Вот мои тесты секундомера за 10000000 итераций:
Чтобы использовать его, вы должны отметить «Разрешить небезопасный код» в свойствах сборки вашего проекта. Согласно .NET Framework 3.5 этот метод также может использоваться как расширение String:
источник
RuntimeHelpers.OffsetToStringData
кратное 8, в версиях .NET для Itanium? Потому что в противном случае это не удастся из-за невыровненных чтений.memcpy
? stackoverflow.com/a/27124232/659190Просто используйте это:
источник
System.Text.ASCIIEncoding.Default.GetBytes("Árvíztűrő tükörfúrógép.").ToString();
вернет"Árvizturo tukörfurogép."
потерянную информацию, которая не может быть восстановлена. (И я еще не упомянул азиатские языки, где вы потеряете все символы.)Строка может быть преобразована в байтовый массив несколькими различными способами из-за следующего факта: .NET поддерживает Unicode, а Unicode стандартизирует несколько разностных кодировок, называемых UTF. Они имеют различную длину представления байтов, но эквивалентны в том смысле, что когда строка кодируется, она может быть закодирована обратно в строку, но если строка закодирована с одним UTF и декодирована в предположении другого UTF, если ее можно прикрутить вверх.
Кроме того, .NET поддерживает не-Unicode-кодировки, но они недопустимы в общем случае (будет действительным, только если ограниченный поднабор кодовой точки Unicode используется в реальной строке, такой как ASCII). Внутри .NET поддерживает UTF-16, но для потокового представления обычно используется UTF-8. Это также стандарт де-факто для Интернета.
Не удивительно, что сериализация строки в массив байтов и десериализация поддерживаются классом
System.Text.Encoding
, который является абстрактным классом; его производные классы поддерживают конкретные кодировки:ASCIIEncoding
и четыре UTF (System.Text.UnicodeEncoding
поддерживает UTF-16)Ссылка на эту ссылку
Для сериализации в массив байтов используется
System.Text.Encoding.GetBytes
. Для обратной операции используйтеSystem.Text.Encoding.GetChars
. Эта функция возвращает массив символов, поэтому для получения строки используйте строковый конструкторSystem.String(char[])
.Ссылка на эту страницу.
Пример:
источник
Это зависит от того, что вы хотите байты для
Это потому, что, как метко сказал Тайлер : «Строки не являются чистыми данными. Они также имеют информацию ». В этом случае информация представляет собой кодировку, которая была принята при создании строки.
Предполагая, что у вас есть двоичные данные (а не текст), хранящиеся в строке
Это основано на комментариях ОП к его собственному вопросу, и это правильный вопрос, если я понимаю подсказки ОП на случай использования.
Хранение двоичных данных в строках, вероятно, является неправильным подходом из-за предполагаемой кодировки, упомянутой выше! Какая бы программа или библиотека не хранила эти двоичные данные в
string
(а не вbyte[]
массиве, который был бы более подходящим), уже проиграл битву до ее начала. Если они отправляют вам байты в виде запроса / ответа REST или чего-либо, что должно передавать строки, Base64 будет правильным подходом.Если у вас есть текстовая строка с неизвестной кодировкой
Все остальные ответили на этот неправильный вопрос неправильно.
Если строка выглядит хорошо, как есть, просто выберите кодировку (желательно, начинающуюся с UTF), используйте соответствующую
System.Text.Encoding.???.GetBytes()
функцию и скажите, кому бы вы ни дали байты, какую кодировку вы выбрали.источник
Когда вас спросили, что вы собираетесь делать с байтами, вы ответили :
Независимо от того, намереваетесь ли вы отправить эти зашифрованные данные по сети, позже загрузить их обратно в память или передать их другому процессу, вы явно собираетесь в какой-то момент расшифровать их. В этом случае ответ таков: вы определяете протокол связи. Протокол связи не должен быть определен с точки зрения деталей реализации вашего языка программирования и связанных с ним времени выполнения. На это есть несколько причин:
Для связи (либо с совершенно разрозненным процессом, либо с той же самой программой в будущем) вам необходимо строго определить свой протокол, чтобы минимизировать сложность работы с ним или случайного создания ошибок. В зависимости от внутреннего представления .NET не является строгим, четким или даже гарантированно согласованным определением. Стандартная кодировка - это строгое определение, которое не подведет вас в будущем.
Другими словами, вы не можете удовлетворить свое требование согласованности без указания кодировки.
Вы, конечно, можете использовать UTF-16 напрямую, если обнаружите, что ваш процесс работает значительно лучше, поскольку .NET использует его внутри или по любой другой причине, но вам нужно выбрать эту кодировку явно и выполнять эти преобразования явно в своем коде, а не в зависимости на внутренней реализации .NET.
Поэтому выберите кодировку и используйте ее:
Как вы можете видеть, на самом деле гораздо меньше кода просто использовать встроенные объекты кодирования, чем реализовать собственные методы чтения / записи.
источник
Два пути:
А также,
Я склонен использовать нижнюю чаще, чем верхнюю, не оценивая их по скорости.
источник
источник