Помещение сообщения в Websphere MQ через C # имеет другую длину данных, чем помещение того же сообщения вручную - PullRequest
8 голосов
/ 11 августа 2011
MQMessage queueMessage = new MQMessage();
                queueMessage.WriteString(strInputMsg);
                queueMessage.Format = MQC.MQFMT_STRING;
                MQPutMessageOptions queuePutMessageOptions = new MQPutMessageOptions();
                Queue.Put(queueMessage, queuePutMessageOptions);

Используя C # с приведенным выше кодом, когда я помещаю сообщение в очередь, длина сообщения составляет 3600.

Когда я вручную вводю сообщение в очередь, щелкая правой кнопкой мыши по очереди и выбирая опцию Поместить тестовое сообщение, длина сообщения составляет 1799.

Я действительно смущен, почему это так. Сообщение в обоих случаях представляет собой строку XML с объявлением. В Notepad ++ есть 1811 символов, включая объявление. Когда я просматриваю сообщение в отладчике перед вводом в очередь, сообщение преобразуется в xml без какой-либо строки или возвратных кареток.

Я создал строку xml, используя:

//converts string message into xml by serializing it
 public string GetMessage(MyMessage messageInstance)
{

// Serialize the request
            XmlSerializer xsr = new XmlSerializer(typeof(MyMessage));
            MemoryStream memoryStream = new MemoryStream();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            xsr.Serialize(xmlTextWriter, messageInstance);

            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
            string XmlizedString = new UTF8Encoding().GetString((memoryStream.ToArray());


            // Encode the xml
            Encoding utf = Encoding.UTF8;
            byte[] utfBytes = utf.GetBytes(XmlizedString);

            // Load the document (XmlResolver is set to null to ingore DTD)
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.XmlResolver = null;
            xmlDoc.LoadXml(utf.GetString(utfBytes));
            return utf.GetString(utfBytes);

Я что-то упустил в своей реализации C #, которая добавляет дополнительные символы?

Спасибо.

1 Ответ

13 голосов
/ 11 августа 2011

Как предполагает @Matten, одной из проблем может быть кодировка символов.

Значением по умолчанию для свойства CharacterSet является 1200 (UNICODE), а WriteString преобразуется в кодовую страницу, указанную CharacterSet.

Кодовая страница 1200 является UTF-16 с прямым порядком байтов, поэтому вы, вероятно, получите два байта на символ. Конечно, возможно, что «Put Test Message» использует другую кодировку, которая использует один байт на символ для общих символов.

Предполагая, что длины 3600 и 1799 подсчитываются в байтах, они могут представлять 1800 символов UTF-16LE и 1799 символов UTF-8 (или 1799 символов ASCII или 1799 символов EBCDIC ...).

Это все еще оставляет нам разницу в длине на один символ. Возможно, WriteString содержит завершающий символ NULL в записанной строке?

Вы уверены, что доверяете счету, который дает вам Notepad ++? Если «Поместить тестовое сообщение» поместило в сообщение 1799 символов, то, возможно, в предоставленных вами данных было 1799 символов.

Редактировать: Предполагая, что теория кодирования верна, вы можете сократить сообщение, используя другую кодировку. То, насколько коротким будет кодирование конкретного сообщения, будет зависеть от фактического содержимого строки.

Например, вы можете использовать кодировку ASCII, чтобы получить один байт на символ.

MQMessage queueMessage = new MQMessage();
queueMessage.CharacterSet = 437;  // Set code page to ASCII

Это сократило бы ваше сообщение до 1800 байт , если все символы в вашей строке xml имели представление ASCII.

Альтернативой может быть использование кодировки UTF-8.

MQMessage queueMessage = new MQMessage();
queueMessage.CharacterSet = 1208;  // Set code page to UTF-8

Преимущество использования UTF-8 состоит в том, что (в отличие от ASCII) все символы имеют представление (для определенных значений «all»). Недостатком является то, что некоторым символам для их представления требуется два, три или даже четыре байта. Наиболее распространенные символы кодируются одним байтом, затем следующие наиболее распространенные символы кодируются двумя байтами и так далее.

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

...