2008-09-23 2 views
7

System.IO.BinaryReader छोटे-छोटे प्रारूप में मान पढ़ता है।एक बाइनरी रीडर से नेटवर्क बाइट-ऑर्डर रूपांतरण को कैसे सरल बना सकता है?

मैं सर्वर साइड पर एक मालिकाना नेटवर्किंग पुस्तकालय से कनेक्ट होने में सी # आवेदन किया है। सर्वर-साइड नेटवर्क बाइट ऑर्डर में सबकुछ नीचे भेजता है, जैसा कि कोई उम्मीद करेगा, लेकिन मुझे लगता है कि क्लाइंट पक्ष पर इसका सामना करना अजीब है, खासकर हस्ताक्षरित मानों के लिए।

UInt32 length = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); 

एक ही रास्ता मैं धारा के बाहर एक सही अहस्ताक्षरित मूल्य प्राप्त करने के साथ आ गया है, लेकिन यह दोनों अजीब और बदसूरत लगता है, और मैं अभी तक अगर है कि बस बंद उच्च क्लिप जा रहा है परीक्षण करने के लिए है -ऑर्डर मान ताकि मुझे मजेदार बिटकॉन्टर सामान करना पड़े।

वहाँ किसी तरह मैं हर पढ़ा पर इन बदसूरत रूपांतरण से बचने के लिए पूरी बात के चारों ओर एक आवरण लेखन से कम याद कर रहा हूँ है? ऐसा लगता है कि पाठकों पर इस तरह की चीजों को आसान बनाने के लिए एंडियन-नेस विकल्प होना चाहिए, लेकिन मैं कुछ भी नहीं मिला हूं।

+0

क्या मूल कोड सही ढंग से काम करता है जब बाइट देशी पूर्णांक का प्रतिनिधित्व कर सकता है? –

+0

अब यह मदद नहीं करेगा, लेकिन मैं/लेखक बॉक्स बाहर Bigendian का समर्थन करने के लिए एक BinaryReder [कनेक्ट टिकट] (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=484149) बनाया। इसके लिए वोट दें [यहां] (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=484149)। –

उत्तर

5

कोई अंतर्निहित कनवर्टर है। यहाँ मेरी आवरण है (जैसा कि आप देख सकते हैं, मैं केवल कार्यक्षमता मैं जरूरत से लागू किया लेकिन संरचना अपने पसंद के हिसाब से बदलने के लिए बहुत आसान है):

/// <summary> 
/// Utilities for reading big-endian files 
/// </summary> 
public class BigEndianReader 
{ 
    public BigEndianReader(BinaryReader baseReader) 
    { 
     mBaseReader = baseReader; 
    } 

    public short ReadInt16() 
    { 
     return BitConverter.ToInt16(ReadBigEndianBytes(2), 0); 
    } 

    public ushort ReadUInt16() 
    { 
     return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0); 
    } 

    public uint ReadUInt32() 
    { 
     return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0); 
    } 

    public byte[] ReadBigEndianBytes(int count) 
    { 
     byte[] bytes = new byte[count]; 
     for (int i = count - 1; i >= 0; i--) 
      bytes[i] = mBaseReader.ReadByte(); 

     return bytes; 
    } 

    public byte[] ReadBytes(int count) 
    { 
     return mBaseReader.ReadBytes(count); 
    } 

    public void Close() 
    { 
     mBaseReader.Close(); 
    } 

    public Stream BaseStream 
    { 
     get { return mBaseReader.BaseStream; } 
    } 

    private BinaryReader mBaseReader; 
} 

असल में, ReadBigEndianBytes घुरघुराना काम करता है, और यह एक करने के लिए पारित हो जाता है BitConverter। यदि आप बड़ी संख्या में बाइट्स पढ़ते हैं तो एक निश्चित समस्या होगी क्योंकि इससे बड़ी स्मृति आवंटन होगी।

+0

नोट: ऐरे Reverse() आपके सरणी के क्रम में जगह को उलट देगा। –

1

मैं एक कस्टम BinaryReader इस सब को संभालने के लिए बनाया गया था। यह part of my Nextem library के रूप में उपलब्ध है। बाइनरी structs को परिभाषित करने का यह एक बहुत ही आसान तरीका है, जो मुझे लगता है कि आपको यहां मदद मिलेगी - उदाहरण देखें।

नोट: यह केवल SVN में अभी है, लेकिन बहुत स्थिर। यदि आपके कोई प्रश्न हैं, तो मुझे cody_dot_brocious_at_gmail_dot_com पर ईमेल करें।

+0

धन्यवाद। मैं एक अतिरिक्त लाइब्रेरी निर्भरता चुनने से बचने की उम्मीद कर रहा था, क्योंकि यह पूरी चीज वास्तव में काफी छोटी और सरल होनी चाहिए, लेकिन मैं इसे ध्यान में रखूंगा। लाइसेंस देखने के लिए अच्छा है, यद्यपि। :) –

+0

आह, मैं देखता हूं। खैर, मुझे आशा है कि यह आपके लिए काम करेगा यदि आप इसके साथ जाना चुनते हैं। और हाँ, मैं इसी कारण से सार्वजनिक डोमेन चला गया - मैं चाहता हूं कि लोग इसके साथ पूरी तरह से कुछ भी करने में सक्षम हों, और घटक इतने छोटे हैं कि पैच वापस प्राप्त करना किसी भी चिंता का नहीं है :) –