2011-08-11 24 views
8
MQMessage queueMessage = new MQMessage(); 
       queueMessage.WriteString(strInputMsg); 
       queueMessage.Format = MQC.MQFMT_STRING; 
       MQPutMessageOptions queuePutMessageOptions = new MQPutMessageOptions(); 
       Queue.Put(queueMessage, queuePutMessageOptions); 

Sử dụng C#, với đoạn code trên, khi tôi nhập vào thông điệp vào hàng đợi, chiều dài dữ liệu của thông điệp là 3600.Đưa tin nhắn trong Websphere MQ qua C# có chiều dài dữ liệu khác nhau hơn so với tay đặt cùng một thông điệp

Khi tôi nhập thủ công thư vào hàng đợi bằng cách nhấp chuột phải vào hàng đợi và chọn tùy chọn Đặt thông báo kiểm tra, độ dài dữ liệu của thư là 1799.

Tôi thực sự bối rối vì lý do này. Thông báo trong cả hai trường hợp là chuỗi xml có khai báo. Trong Notepad ++, có 1811 ký tự bao gồm cả khai báo. Khi tôi xem thông báo trong trình gỡ rối trước khi tôi nhập vào hàng đợi, thông báo được chuyển đổi thành xml mà không có bất kỳ dòng hoặc trả lại toa xe nào.

Tôi tạo ra chuỗi xml sử dụng:

//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); 

Am tôi thiếu bất cứ điều gì trong C thực hiện của tôi # mà sẽ bổ sung thêm các ký tự?

Cảm ơn.

+2

UTF8 vs ASCII? – Matten

Trả lời

12

Vì @Matten đề xuất một vấn đề có thể là mã hóa ký tự.

Giá trị mặc định cho thuộc tính CharacterSet là 1200 (UNICODE) và WriteString chuyển đổi thành trang mã được chỉ định bởi CharacterSet.

Mã trang 1200 là UTF-16 little-endian để bạn có thể nhận được hai byte cho mỗi ký tự. Nó chắc chắn có thể là "Put Test Message" sử dụng một số mã hóa khác sử dụng một byte cho mỗi ký tự cho các ký tự phổ biến.

Giả sử rằng độ dài 3600 và 1799 được tính theo byte, chúng có thể biểu thị 1800 ký tự UTF-16LE và 1799 ký tự UTF-8 (hoặc 1799 ký tự ASCII hoặc 1799 ký tự EBCDIC ...).

Điều đó vẫn khiến chúng tôi có độ dài khác biệt một ký tự. Có lẽ WriteString bao gồm một ký tự NULL kết thúc trong chuỗi được viết?

Bạn có chắc là bạn tin tưởng số Notepad ++ cung cấp cho bạn? Nếu đưa tin nhắn thử nghiệm đặt 1799 ký tự vào một tin nhắn có thể có 1799 ký tự trong dữ liệu bạn cung cấp cho nó.

Chỉnh sửa: Giả sử lý thuyết mã hóa là chính xác, bạn có thể rút ngắn thông báo bằng cách sử dụng mã hóa khác. Cách mã hóa ngắn sẽ làm cho một thông điệp cụ thể sẽ phụ thuộc vào nội dung thực tế của chuỗi.

Ví dụ: bạn có thể sử dụng mã hóa ASCII để nhận một byte cho mỗi ký tự.

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

Điều đó sẽ rút ngắn thông điệp của bạn tới 1800 byte nếu tất cả các nhân vật trong chuỗi xml của bạn đã có một đại diện ASCII.

Cách khác là sử dụng mã hóa UTF-8.

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

Sử dụng UTF-8 có lợi thế (không giống như ASCII) tất cả các ký tự đều có đại diện (với giá trị nhất định 'tất cả'). Điểm bất lợi là một số ký tự yêu cầu hai, ba hoặc thậm chí bốn byte để đại diện cho chúng.Các ký tự phổ biến nhất được mã hóa trong một byte, sau đó các ký tự phổ biến nhất tiếp theo được mã hóa thành hai byte và cứ như vậy.

Trong trường hợp tốt nhất, mã hóa UTF-8 cũng sẽ cung cấp cho bạn 1800 byte. Trong trường hợp xấu nhất nó sẽ cung cấp cho bạn 7200 byte nhưng điều đó dường như rất khó trừ khi bạn đang sử dụng một cái gì đó như Klingon!

+0

làm cách nào để đảm bảo rằng chuỗi đã nhập là 1799 ký tự chứ không phải 3600? – InfoLearner

+1

Cảm ơn Frank bạn đã lưu trong ngày !!! – PAVITRA

+0

Ngoài ra, như tôi vừa mới phát hiện ra - nếu bạn đặt ký tự được đặt thành 1208 (UTF), hãy đảm bảo bạn sử dụng WriteString chứ không phải WriteUTF vì UTF này mã hóa UTF! – nik0lias

Các vấn đề liên quan