2009-09-14 11 views
19

तो यहाँ सौदा है: मैं (बाइट्स से) एक फ़ाइल खोलने के लिए, शीर्षक में कुछ मेटाडाटा के साथ गड़बड़ कर सकते हैं तो मैं एक स्ट्रिंग के लिए परिवर्तित कोशिश कर रहा हूँ, इसे वापस कन्वर्ट बाइट्स के लिए, और इसे बचाओ। जिस समस्या में मैं अभी चल रहा हूं वह इस कोड के साथ है। जब मैं उस स्ट्रिंग की तुलना करता हूं जिसे मूल बाइट सरणी में आगे और आगे परिवर्तित किया गया है (लेकिन अन्यथा संशोधित नहीं किया गया है), यह असमान है। मै इसे काम मे कैसे ले सकता हूँ?सी # में स्ट्रिंग के लिए बाइट सरणी परिवर्तित और फिर से वापस

public static byte[] StringToByteArray(string str) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    return encoding.GetBytes(str); 
} 

public string ByteArrayToString(byte[] input) 
{ 
    UTF8Encoding enc = new UTF8Encoding(); 
    string str = enc.GetString(input); 
    return str; 
} 

यहां बताया गया है कि मैं उनकी तुलना कैसे कर रहा हूं।

byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length)); 
string fileDataString = ByteArrayToString(fileData); 
byte[] recapturedBytes = StringToByteArray(fileDataString); 
Response.Write((fileData == recapturedBytes)); 

मुझे यकीन है कि यह UTF-8 है, का उपयोग कर रहा हूँ:

StreamReader sr = new StreamReader(filesindir[0]); 
Response.Write(sr.CurrentEncoding); 

जो "System.Text.UTF8Encoding" देता है।

+6

क्या आप वाकई इसके यूटीएफ -8 से शुरुआत कर रहे हैं? –

+0

मुझे यकीन नहीं है। मैं कैसे बताउंगा कि यह है या नहीं? –

+0

आपका क्या मतलब है, यह असमान है? आपकी स्ट्रिंग असमान है? आपको एक ही स्ट्रिंग परिणाम नहीं मिलता है? – Khan

उत्तर

16

Encoding वर्ग है कि आप विभिन्न एन्कोडिंग के उदाहरण के साथ प्रदान करता है पर स्थिर कार्यों की कोशिश करो। आपको बाइट सरणी में/से कनवर्ट करने के लिए Encoding को तुरंत चालू करने की आवश्यकता नहीं है। कोड में स्ट्रिंग की तुलना कैसे कर रहे हैं?

संपादित

आप सरणियों, नहीं तार तुलना कर रहे हैं। वे असमान हैं क्योंकि वे दो अलग-अलग सरणी का उल्लेख करते हैं; == ऑपरेटर का उपयोग केवल उनके संदर्भों की तुलना करेगा, न कि उनके मूल्यों। यह निर्धारित करने के लिए कि क्या वे बराबर हैं, आपको सरणी के प्रत्येक तत्व का निरीक्षण करना होगा।

public bool CompareByteArrays(byte[] lValue, byte[] rValue) 
{ 
    if(lValue == rValue) return true; // referentially equal 
    if(lValue == null || rValue == null) return false; // one is null, the other is not 
    if(lValue.Length != rValue.Length) return false; // different lengths 

    for(int i = 0; i < lValue.Length; i++) 
    { 
     if(lValue[i] != rValue[i]) return false; 
    } 

    return true; 
} 
+0

मैंने यह दिखाने के लिए प्रश्न संपादित किया है कि कैसे ... टिप्पणी में कोड सही दिखाई नहीं देता है! –

+0

मैंने कोशिश की, वे वापस लौटते हैं कि वे एक ही लंबाई के नहीं हैं। यह कहीं और होना चाहिए। –

+3

यूटीएफ 8 एन्कोडिंग के लिए प्रलेखन पर नज़र डालें। प्रस्तावना निर्दिष्ट करना है या नहीं, इसके लिए एक विकल्प है। यदि आप पाते हैं कि आपकी जेनरेट बाइट सरणी मूल से अधिक है, तो संभवतः आपकी समस्या है। दोबारा, आपको यह सुनिश्चित करने की ज़रूरत है कि यूटीएफ 8 वास्तव में सही एन्कोडिंग है। आप कैसे कह सकते हैं, आपको यह पूछना होगा कि जो भी आपको डेटा के साथ आपूर्ति कर रहा है। –

3

आपकी समस्या जिस तरह से आप बाइट्स की सरणी तुलना कर रहे हैं प्रतीत होता:, नहीं

Response.Write((fileData == recapturedBytes)); 

यह हमेशा अवास्तविक लौटाते हैं जब से तुम बाइट सरणी के पते की तुलना कर रहे इसमें मूल्य शामिल हैं। स्ट्रिंग डेटा की तुलना करें, या बाइट सरणी की तुलना करने की विधि का उपयोग करें। आपको चाहिए भी नहीं प्रयास को

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes)); 
5

कारण तथ्य यह है कि नेट तार यूनिकोड तार का उपयोग करने के, आप अब इस तरह लोगों को सी में किया था ज्यादातर मामलों में कर सकते हैं,: आप भी इस के बजाय कर सकता है स्ट्रिंग < -> बाइट सरणी से आगे और आगे जाएं जब तक सामग्री वास्तव में टेक्स्ट नहीं है।

मैं इस बिंदु स्पष्ट करना है:, नेट में अगर byte[] डेटा पाठ नहीं है, तो एक पाठ पर बाइनरी डेटा के लिए विशेष Base64 एन्कोडिंग के अलावा एक string करने के लिए इसे परिवर्तित करने के लिए प्रयास नहीं करते चैनल। यह उन लोगों के बीच व्यापक रूप से गलतफहमी है जो .NET में काम करते हैं।

+4

स्ट्रिंग <-> बाइट [] रूपांतरण आमतौर पर सिस्टम में से एक के माध्यम से किया जाना चाहिए। टेक्स्ट। एन्कोडिंग कक्षाएं, बिटकॉन्टर वर्ग नहीं। BitConverter.ToString संख्याओं के हेक्साडेसिमल स्ट्रिंग प्रस्तुति में एक बाइट सरणी को परिवर्तित करता है, यह ** एक ** बाइट सरणी को एक स्ट्रिंग में परिवर्तित नहीं करता है। –

+1

हे, मुझे पता था कि मुझे उस पंक्ति को हटा देना चाहिए था जब मुझे पता था कि यह मेरी पोस्ट का मुद्दा नहीं था। –

7

आप कच्चे बाइट (8 बिट संभवतः-नहीं-मुद्रण योग्य अक्षर) हैं और उन्हें एक .NET स्ट्रिंग के रूप में हेरफेर और बाइट्स में उन्हें फिर से चालू करना चाहते हैं, तो आप

Encoding.GetEncoding(1252) 

का उपयोग करके ऐसा कर सकते हैं यूटीएफ 8 एन्कोडिंग के बजाय। वह एन्कोडिंग किसी भी 8-बिट मान लेने के लिए काम करता है और इसे किसी भी जानकारी को खोए बिना, .NET 16-बिट char में परिवर्तित करता है, और फिर वापस।

बाइनरी फ़ाइल के साथ ऊपर वर्णित विशिष्ट मामले में, आप "शीर्षलेख में मेटाडेटा के साथ गड़बड़" करने में सक्षम नहीं होंगे और जब तक आपके द्वारा गड़बड़ किए गए डेटा की लंबाई अपरिवर्तित नहीं हो जाती है तब तक चीजें सही तरीके से काम नहीं कर पाती हैं। उदाहरण के लिए, यदि शीर्षलेख में

{any}{any}ABC{any}{any} 

और आप एबीसी को डीईएफ में बदलना चाहते हैं, जो आपको पसंद करना चाहिए। लेकिन अगर आप एबीसी को डब्ल्यूएक्सवाईजेड में बदलना चाहते हैं, तो आपको बाइट पर लिखना होगा जो "सी" का पालन करता है या आप (संक्षेप में) सब कुछ एक बाइट को दाईं ओर ले जाएंगे। एक सामान्य बाइनरी फ़ाइल में, यह गड़बड़ चीजों को बहुत अधिक कर देगा।

यदि "एबीसी" के बाद बाइट रिक्त स्थान या शून्य वर्ण हैं, तो एक बेहतर मौका है कि बड़े प्रतिस्थापन डेटा लिखने से परेशानी नहीं होगी - लेकिन आप अभी भी .NET स्ट्रिंग में WXYZ के साथ एबीसी को प्रतिस्थापित नहीं कर सकते हैं, इसे लंबे समय तक बनाते हैं - आपको WXYZ के साथ एबीसी {whatever_follows_it} को प्रतिस्थापित करना होगा। यह देखते हुए, आप पाते हैं कि डेटा को बाइट्स के रूप में छोड़ना और एक समय में एक बाइट प्रतिस्थापन डेटा लिखना आसान है।

+0

यदि किसी के पास बाइट्स की एक सरणी है और किसी विशेष अनुक्रम की सभी घटनाओं को एक अलग लंबाई के दूसरे अनुक्रम के साथ बदलने की इच्छा है (उदाहरण के लिए {0x7D, 0x5E} की सभी घटनाओं को {0x7E} के साथ बदलें, तो 'स्ट्रिंग का उपयोग करके स्ट्रिंग में परिवर्तित हो जाएगा Resplace', और फिर वापस परिवर्तित एक उचित दृष्टिकोण हो? क्या उपर्युक्त एन्कोडिंग प्रत्येक बाइट मान 0-255 को इसके समान समान संख्या वाले कोड के साथ प्रतिस्थापित करेगा [तथ्य यह है कि एन्कोडिंग लापरवाह है, वह स्वयं ही इसका अर्थ नहीं देगी]? – supercat

+0

@supercat - हाँ वह दृष्टिकोण (बशर्ते आप 1252 एन्कोडिंग का उपयोग करें) काम करेगा। लेकिन आप अभी भी मेरे संदेश में उल्लिखित कारणों के लिए अधिकांश बाइनरी फ़ाइल स्वरूपों के साथ ऐसा करने में सक्षम नहीं होंगे। –

+0

यदि कोई स्थिति-संवेदनशील प्रारूपों का उपयोग कर रहा है तो किसी को स्पष्ट रूप से यह सुनिश्चित करना होगा कि ऐसी चीजें जिन्हें स्थानांतरित नहीं किया जाना चाहिए, नहीं। फिर भी, ऐसे मामले होंगे जहां "मूल" और "प्रतिस्थापन" तार समान लंबाई के समान 'स्ट्रिंग। रीप्लेस' उपयोगी लगेगा। – supercat

संबंधित मुद्दे