Поток памяти из строки — путаница в используемой кодировке

#c# #.net #encoding

#c# #.net #кодирование

Вопрос:

У меня есть фрагмент кода, который преобразует строку в поток памяти:

 using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(applicationForm)))
  

Однако я немного смущен, правильно ли это. В принципе, я всегда в замешательстве.Сетевое кодирование.

Итог: правильно ли я использую объект encoding (UTF8) для получения байтов?

Я знаю это внутренне.NET хранит строку как UTF-16, но моя переменная applicationForm была основана на файле с текстом, который был сохранен в кодировке UTF-8.

Спасибо, Павел

ПРАВКА 1: Давайте точно объясним, как я получаю переменную applicationForm. У меня действительно есть доступ к сборке, которая предоставляет класс с помощью метода GenerateApplicationForm. Этот метод возвращает строку. Однако я знаю, что где-то за кулисами компонент использует файлы, хранящиеся на диске.Содержимое этих файлов закодировано с использованием UTF-8. Поэтому я не могу прочитать файл напрямую и т.д. У меня есть только эта строка, и я знаю, что изначально использовался файл в кодировке UTF-8. В клиентском коде, который использовал компонент GenerateApplicationForm , я должен преобразовать переменную applicationForm в stream, потому что другие компоненты (из другой сборки) ожидают Stream. Вот тут-то и вступает в действие использование …. заявления, упомянутого в вопросе.

Комментарии:

1. Если это сработает, не трогайте его.

2. Но это зависит от данных, с которыми вы работаете.

3. чего вы пытаетесь достичь? как заполняется applicationForm? это строка… в памяти он находится в формате utf-16, даже если он был загружен из файла utf-8

4. Какие типы кодирования поддерживает компонент GenerateApplicationForm в переданном потоке? В этом суть вопроса.

5. UTF-8. GenerateApplicationForm фактически используется в каком-то посреднике. Этот посредник: а) получает строку (от компонента X, который на самом деле является GenerateApplicationForm, который генерирует формы приложений) б) преобразует строку в поток с) передает поток компоненту Y. Компонент Y ожидает поток в кодировке UTF-8.

Ответ №1:

Предполагается, что applicationForm это строка, которую вы прочитали из некоторого UTF8 текстового файла. Это будет UTF16 / Unicode , независимо от кодировки исходного файла. Преобразование произошло, когда вы загрузили файл в строку.

Ваш код будет кодировать applicationForm строку в MemoryStream количество UTF8 байтов.

Это может быть или не быть правильным в зависимости от того, что вы хотите с этим сделать.

Строки .Net всегда являются UTF16 или Unicode . При Strings преобразовании в файлы, потоки или byte[] они могут быть закодированы различными способами. 1 байта недостаточно для хранения всех различных символов, используемых на всех языках, поэтому необходимо закодировать более сложные строки, чтобы один символ мог быть представлен более чем одним байтом, иногда или всегда, в зависимости от используемой кодировки.

Если вы используете простую кодировку, подобную ASCII , один символ всегда будет состоять из одного байта, но данные будут ограничены ASCII набором символов. Преобразование в ‘ASCII’ из любой кодировки UTF может привести к потере данных, если используются какие-либо многобайтовые символы.

Для получения полной картины о юникоде перейдите сюда.

РЕДАКТИРОВАТЬ 1: Исключая дополнительную информацию о компоненте GenerateApplicationForm, завершение UTF8 , вероятно, будет правильным выбором. Если это не сработает, попробуйте ASCII или UTF16 . Лучше всего проконсультироваться с исходным кодом компонента или поставщиком компонента.

РЕДАКТИРОВАТЬ 2: Определенно UTF8 тогда вы были правы с самого начала.

Комментарии:

1. Я добавил некоторые детали к вопросу. Возможно, это поможет решить проблему, с которой я имею дело. Спасибо

2. Какие типы кодирования поддерживает компонент GenerateApplicationForm в переданном потоке? В этом суть вопроса.

3. UTF-8. GenerateApplicationForm фактически используется в каком-то посреднике. Этот посредник: а) получает строку (от компонента X, который на самом деле является GenerateApplicationForm, который генерирует формы приложений) б) преобразует строку в поток с) передает поток компоненту Y. Компонент Y ожидает поток в кодировке UTF-8.

4. Хорошо, я думаю, что начинаю понимать. Итак, решающий вывод: Encoding.UTF8. Строка getBytes(applicationForm)) выполняет «на лету» преобразование строкового представления UTF-16 в .NET в UTF-8?

5. Сравнение «на лету» не выполняется — смотрите Мой ответ. Он принимает текстовое представление двоичного значения и превращает его обратно в двоичное. Это не имеет никакого отношения к тому, как . NET обрабатывает строки внутренне.

Ответ №2:

Если данные сохранены в UTF-8, то вам нужно открыть их с помощью UTF-8.

Комментарии:

1. В принципе, я не открываю данные. Пожалуйста, проверьте мою ПРАВКУ в вопросе.

Ответ №3:

Просто используйте для чтения ту же кодировку, что и при записи. Если бы это был UTF8 -> использовать UTF8. Если вы пишете по-китайски, кто-то должен уметь читать по-китайски, чтобы понимать вас…

Ответ №4:

Для UTF-8 в начале файла должна быть добавлена метка порядка байтов (BOM). Видите, что файл имеет формат utf-8, тогда используйте конвертер utf-8.

Комментарии:

1. Я добавил некоторую информацию к вопросу. Пожалуйста, проверьте, все ли еще актуален ваш ответ.

Ответ №5:

Кодировка в байтах UTF8 создает представление ваших данных, которое обратно совместимо с набором символов ASCII для представления ваших данных. Поскольку ASCII является наименьшим общим знаменателем для передачи данных, вы можете в значительной степени гарантировать, что это представление будет работать в подавляющем большинстве систем.

Хотя вы могли бы это изменить, вы предполагаете, что любая система, к которой это относится, тоже поймет, что вы изменили ее, и будет поддерживать ваше новое представление. Это довольно сложное предположение для проверки. Кодировки на обоих концах во многом совпадают.

Если, как вы говорите, вы не можете изменить систему, которая генерирует вашу строку, то да, вы делаете это правильно. Это работает, так почему вы считаете, что вам нужно вносить изменения? Внутренности того, как .NET представляет собой строку, здесь не имеет значения, вы получаете не строку .NET, вы получаете представление значения в кодировке UTF-8, поэтому вы должны использовать UTF8 для декодирования его в исходное значение.