2012-08-27 2 views
34

में यूटीएफ 8 के रूप में एक स्ट्रिंग संग्रहीत करना मैं सी # में बहुत सी स्ट्रिंग मैनिपुलेशन कर रहा हूं, और वास्तव में तारों को एक बाइट प्रति स्टोर करने की आवश्यकता है। ऐसा इसलिए है क्योंकि मुझे स्मृति में एक साथ टेक्स्ट के गीगाबाइट की आवश्यकता होती है और इससे कम स्मृति समस्याएं उत्पन्न होती हैं। मुझे निश्चित रूप से पता है कि इस पाठ में कभी भी गैर-ASCII वर्ण नहीं होंगे, इसलिए मेरे उद्देश्यों के लिए, यह तथ्य कि System.String और System.Char प्रत्येक चरित्र को दो बाइट्स के रूप में स्टोर करता है, दोनों अनावश्यक और वास्तविक समस्या दोनों हैं।सी #

मैं अपने स्वयं के CharAcicii और StringAscii कक्षाओं को कोडिंग शुरू करने वाला हूं - स्ट्रिंग मूल रूप से बाइट [] के रूप में अपना डेटा रखेगी और स्ट्रिंग मैनिपुलेशन विधियों का खुलासा करेगी जो System.String करता है। हालांकि ऐसा लगता है कि ऐसा कुछ ऐसा करने के लिए बहुत काम करता है जो एक बहुत ही मानक समस्या की तरह लगता है, इसलिए मैं वास्तव में यह जांचने के लिए यहां पोस्ट कर रहा हूं कि पहले से ही कोई आसान समाधान नहीं है। क्या उदाहरण के लिए मैं सिस्टम बना सकता हूं। स्ट्रिंग आंतरिक रूप से डेटा को यूटीएफ 8 के रूप में संग्रहीत करता है जिसे मैंने देखा नहीं है, या समस्या के चारों ओर किसी अन्य तरीके से?

+0

क्या .NET यहां जाने का सबसे अच्छा तरीका है? ऐसा लगता है जैसे सी/सी ++ स्मृति में विशाल तारों के हेरफेर के लिए बेहतर विकल्प होगा। –

+4

जॉन स्कीट ने इस पिछले वर्ष की जांच की http://msmvps.com/blogs/jon_skeet/archive/2011/04/05/of-memory-and-strings.aspx –

+0

[कहीं और] (http://msdn.microsoft.com /en-us/library/windows/desktop/bb540816%28v=vs.85%29.aspx) एक utf8 स्ट्रिंग – Gabber

उत्तर

6

जैसा कि आपने पाया है, सीएलआर चरित्र एन्कोडिंग के लिए यूटीएफ -16 का उपयोग करता है। आपका सर्वोत्तम शर्त टेक्स्ट को संभालने के लिए एन्कोडिंग कक्षा & बिट बिट कनवर्टर का उपयोग करना हो सकता है। यह सवाल दो एन्कोडिंग के बीच परिवर्तित करने के लिए कुछ अच्छे उदाहरण हैं:

Convert String (UTF-16) to UTF-8 in C#

+0

धन्यवाद। इसे उत्तर के रूप में चिह्नित करें क्योंकि लिंक में रूपांतरण करने के बारे में बहुत सारी जानकारी है। मुझे लगता है कि आप और कीथ्स का सुझाव शायद अधिकतम प्रदर्शन के बीच मेरी स्थिति में सबसे अच्छा समझौता है और किसी प्रकार का समाधान प्राप्त करना जो लागू करने में बहुत लंबा समय लगे स्मृति को बचाता है। – PhantomDrummer

11

ठीक है, आप एक रैपर बना सकते हैं जो डेटा को यूटीएफ -8 बाइट्स के रूप में पुनर्प्राप्त करता है और सिस्टम के लिए आवश्यक टुकड़ों को परिवर्तित करता है। स्ट्रिंग, फिर स्ट्रिंग को मेमोरी में वापस धक्का देने के विपरीत। एन्कोडिंग क्लास आपको यहां मदद करेगा:

var utf8 = Encoding.UTF8; 
byte[] utfBytes = utf8.GetBytes(myString); 

var myReturnedString = utf8.GetString(utfBytes); 
+0

+1, मैंने एक रियल एस्टेट कंपनी और इस समाधान के लिए डेटा की भारी मात्रा में कटाई करते समय खुद को इस समस्या की जांच की, जबकि थोड़ी जादुई और प्रतीत होता है कि यह बहुत अच्छी चीज है जिसे मैं सी # में आने में सक्षम था। – tmesser

+0

यह यूटीएफ -16 एन्कोडेड स्ट्रिंग ऑब्जेक्ट में, रास्ते में समाप्त होता है। – Tigran

+0

@ टिग्रान, अगर आप किसी भी बिंदु पर System.String का उपयोग करने जा रहे हैं, तो इसके आसपास जाने का कोई तरीका नहीं है। हालांकि, आप एन्कोडेड बाइट सरणी के उपखंडों को खींच सकते हैं और उन्हें नियंत्रित तरीके से लिख सकते हैं, जिससे आप कितने संसाधनों को चूस रहे हैं, इसकी ऊपरी सीमा छोड़कर। – tmesser

2

नहीं वास्तव में। System.String तारों को संग्रहित करने के लिए डिज़ाइन किया गया है। आपकी आवश्यकता विशेष स्मृति लाभ के साथ तारों के एक बहुत ही विशेष सबसेट के लिए है।

अब, "विशेष स्मृति लाभों के साथ तारों का बहुत विशेष सबसेट" बहुत कुछ आता है, लेकिन हमेशा एक ही विशेष सबसेट नहीं होता है। कोड जो ASCII- केवल मनुष्यों द्वारा पढ़ने के लिए नहीं है, इसलिए यह या तो छोटे कोड या कुछ ऐसा होता है जिसे धारा-प्रसंस्करण तरीके से संभाला जा सकता है, या अन्यथा अन्य नौकरियों को करने वाले बाइट्स के साथ विलय किए गए पाठ के भाग (उदाहरण के लिए कुछ बाइनरी प्रारूपों में छोटे बिट्स होंगे जो सीधे ASCII में अनुवाद करते हैं)।

इस तरह, आपके पास एक बहुत ही अजीब आवश्यकता है।

और भी जब आप गीगाबाइट भाग में आते हैं। अगर मैं गigs से निपट रहा हूं, तो मैं तुरंत सोच रहा हूं कि मैं गigs से निपटने के लिए कैसे रोक सकता हूं, और/या केवल 50% से ज्यादा गंभीर बचत प्राप्त कर सकता हूं। मैं उन हिस्सों को मैप करने के बारे में सोच रहा हूं जिन्हें मैं वर्तमान में किसी फ़ाइल में, या रस्सियों के बारे में, या अन्य चीजों के समूह के बारे में नहीं सोच रहा हूं। बेशक, वे कुछ मामलों के लिए काम करने जा रहे हैं, न कि सभी के लिए, फिर भी, हम किसी चीज़ के बारे में बात नहीं कर रहे हैं जहां .NET को एक आकार के रूप में फिट होना चाहिए-सब कुछ, क्योंकि एक आकार फिट नहीं होगा सब।

इसके अलावा, केवल utf-8 बिट इतना कठिन नहीं है। यह अन्य सभी विधियां हैं जो काम बन जाती हैं। दोबारा, आपको जो चाहिए वह किसी और के समान नहीं होगा।

+3

यह इतना अजीब नहीं है। ओपी स्ट्रिंग्स चाहता है जो 'System.String' के समान काम करते हैं, लेकिन आधे स्थान लेते हैं। दूसरे शब्दों में एक ड्रॉप-इन प्रतिस्थापन। –

+0

@RobertHarvey हां, लेकिन वे उदा। ओ (एन) लंबाई नहीं चाहेंगे क्योंकि उन्हें पता है कि उन्हें अपने डेटा के ज्ञान से इसकी आवश्यकता नहीं है। किसी भी यूटीएफ -8 आधारित स्ट्रिंग के लिए समान लेकिन समान आवश्यकताओं वाले किसी को ओ (एन) गिनती की आवश्यकता नहीं होगी क्योंकि वे केवल ASCII तक चिपके नहीं हैं। सामान्य समस्या बहुत अधिक आती है, लेकिन छोटे विवरण अलग-अलग होते हैं और इससे एक व्यक्ति के सही ड्रॉप-इन को दूसरे व्यक्ति के जहर को प्रतिस्थापित किया जाता है। –

+0

रॉबर्ट हार्वे के पास यह बिल्कुल है। जॉन - मैं जो कर रहा हूं, बहुत मोटे तौर पर, टेक्स्ट के बिट्स के बीच व्यापक क्रॉस-रेफरेंसिंग शामिल है। इस प्रकार, प्रसंस्करण के दौरान पूरे पाठ को स्मृति में रखने से बचना बहुत मुश्किल होगा। लेखन भाग मैं तुरंत फाइल में दिलचस्पी नहीं लेता हूं, उन्हें बाद में उन्हें एक मिलीसेकंड वापस पढ़ना होगा, क्या मैं कल्पना करता हूं कि प्रदर्शन के लिए डरावना हो! (साथ ही साथ कोड को और जटिल बनाते हैं) – PhantomDrummer

1

जैसा कि मैं आपकी समस्या देख सकता हूं कि सी # में चार एक के बजाय 2 बाइट्स पर कब्जा कर रहा है।

System.IO.FileStream fs = new System.IO.FileStream(file, System.IO.FileMode.Open); 
    System.IO.BinaryReader br = new System.IO.BinaryReader(fs); 

    byte[] buffer = new byte[1024]; 
    int read = br.Read(buffer, 0, (int)fs.Length); 

    br.Close(); 
    fs.Close(); 

और इस तरह आप फ़ाइल से बाइट्स पढ़ रहे हैं:

एक तरह से एक पाठ फ़ाइल को पढ़ने के लिए के साथ इसे खोलने के लिए है। मैंने इसे * के साथ करने की कोशिश की।txt फ़ाइलें UTF-8 है कि चार प्रति 2 बाइट्स, और एएनएसआई है कि चार प्रति 1 बाइट में इनकोडिंग।

+0

क्या आपका मतलब यूटीएफ -16 है? यूटीएफ -8, एएनएसआई की तरह, मैं जिस विशेष डेटा के बारे में पूछ रहा हूं उसके लिए 1 बाइट प्रति चार हो। लेकिन धन्यवाद, वास्तव में वास्तव में मैं डेटा पढ़ रहा हूं। – PhantomDrummer

+0

@PantomDrummer मैंने वास्तव में यूटीएफ -8 की कोशिश की, नोटपैड सामान्य एन्कोडिंग, और यह प्रति चार बाइट ले लिया :) मदद करने में खुशी – Thanatos