2008-08-21 24 views
26

मैं स्मृति में एक बाइट सरणी है, एक फ़ाइल से पढ़ने विभाजित करने के लिए कैसे। मैं बाइट सरणी को एक निश्चित बिंदु (इंडेक्स) पर विभाजित करना चाहता हूं, बिना किसी नए बाइट सरणी को बनाए और एक बार में प्रत्येक बाइट की प्रतिलिपि बनाना, ऑपरेशन के मेमोरी पैर प्रिंट में वृद्धि करना।एक बाइट सरणी

byte[] largeBytes = [1,2,3,4,5,6,7,8,9]; 
byte[] smallPortion; 
smallPortion = split(largeBytes, 3); 

smallPortion बराबर 1,2,3,4
largeBytes 5,6,7,8,9

उत्तर

14

यह मैं यह कैसे कर देगी:

using System; 
using System.Collections; 
using System.Collections.Generic; 

class ArrayView<T> : IEnumerable<T> 
{ 
    private readonly T[] array; 
    private readonly int offset, count; 

    public ArrayView(T[] array, int offset, int count) 
    { 
     this.array = array; 
     this.offset = offset; 
     this.count = count; 
    } 

    public int Length 
    { 
     get { return count; } 
    } 

    public T this[int index] 
    { 
     get 
     { 
      if (index < 0 || index >= this.count) 
       throw new IndexOutOfRangeException(); 
      else 
       return this.array[offset + index]; 
     } 
     set 
     { 
      if (index < 0 || index >= this.count) 
       throw new IndexOutOfRangeException(); 
      else 
       this.array[offset + index] = value; 
     } 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     for (int i = offset; i < offset + count; i++) 
      yield return array[i]; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     IEnumerator<T> enumerator = this.GetEnumerator(); 
     while (enumerator.MoveNext()) 
     { 
      yield return enumerator.Current; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; 
     ArrayView<byte> p1 = new ArrayView<byte>(arr, 0, 5); 
     ArrayView<byte> p2 = new ArrayView<byte>(arr, 5, 5); 
     Console.WriteLine("First array:"); 
     foreach (byte b in p1) 
     { 
      Console.Write(b); 
     } 
     Console.Write("\n"); 
     Console.WriteLine("Second array:"); 
     foreach (byte b in p2) 
     { 
      Console.Write(b); 
     } 
     Console.ReadKey(); 
    } 
} 
0

आप नहीं कर सकते हैं के बराबर होगा: क्या मैं चाहूँगा कुछ इस तरह है। आप जो चाहते हैं वह शुरुआती बिंदु और वस्तुओं की संख्या रखना है; संक्षेप में, iterators का निर्माण। यदि यह सी ++ है, तो आप केवल std::vector<int> का उपयोग कर सकते हैं और अंतर्निहित लोगों का उपयोग कर सकते हैं।

सी # में, मैं एक छोटे से इटरेटर वर्ग कि सूचकांक शुरू रखती निर्माण गिनती और IEnumerable<> लागू करता था।

1

मुझे यकीन है कि तुम क्या मतलब है द्वारा नहीं कर रहा हूँ:

मैं एक निश्चित बिंदु पर बाइट सरणी विभाजित करने के लिए चाहते हैं (इंडेक्स) एक नया बाइट सरणी बनाने के बिना और एक बार में प्रत्येक बाइट की प्रतिलिपि बनाने के बिना, ऑपरेशन के मेमोरी पैर प्रिंट में वृद्धि।

सबसे अधिक भाषाओं में, निश्चित रूप से सी #, एक बार एक सरणी आबंटित किया गया है, वहाँ कोई रास्ता नहीं है इसके बारे में आकार बदलने के लिए है। ऐसा लगता है कि आप एक सरणी की लंबाई बदलने के लिए एक रास्ता तलाश रहे हैं, जिसे आप नहीं कर सकते। आप दूसरी सरणी बनाने के लिए किसी भी तरह सरणी के दूसरे भाग के लिए मेमोरी रीसायकल करना चाहते हैं, जिसे आप भी नहीं कर सकते हैं।

सारांश में: बस एक नई सरणी पैदा करते हैं।

17
FYI करें

System.ArraySegment<T> संरचना मूल रूप से उपरोक्त कोड में ArrayView<T> जैसी ही चीज़ है। यदि आप चाहें तो आप इस आउट ऑफ़ द बॉक्स संरचना का उसी तरह उपयोग कर सकते हैं।

+0

दिलचस्प। बहुत बुरा मैंने उस परियोजना को काम करते समय यह नहीं देखा। जो भी हो, जानकारी के लिए शुक्रिया। –

13

सी # LINQ के साथ में आप यह कर सकते हैं:

smallPortion = largeBytes.Take(4).ToArray(); 
largeBytes = largeBytes.Skip(4).Take(5).ToArray(); 

;)

+3

ओपी ऐसा करने के तरीके सोच है ** बिना [...] एक नया बाइट सरणी बना सकते हैं और एक समय में प्रत्येक बाइट कॉपी ** लेकिन वह वास्तव में क्या आपके LINQ कोड करता है। दो बार। –

+0

..this मुझे एक समस्या मुझे लगता है कि 'ArraySegment ' .. – AceMark

+0

@Christian द्वारा हल नहीं जा सके थे, adittional स्मृति का उपयोग सिर्फ दोनों ".ToArray()" कॉल निकालने से बचने के लिए किया था का समाधान में मदद की। वह दो आईनेमरेबल्स को कोड की बहुत कम लाइनों के साथ वापस कर देगा। –

3

इस एक का प्रयास करें:

private IEnumerable<byte[]> ArraySplit(byte[] bArray, int intBufforLengt) 
    { 
     int bArrayLenght = bArray.Length; 
     byte[] bReturn = null; 

     int i = 0; 
     for (; bArrayLenght > (i + 1) * intBufforLengt; i++) 
     { 
      bReturn = new byte[intBufforLengt]; 
      Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt); 
      yield return bReturn; 
     } 

     int intBufforLeft = bArrayLenght - i * intBufforLengt; 
     if (intBufforLeft > 0) 
     { 
      bReturn = new byte[intBufforLeft]; 
      Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft); 
      yield return bReturn; 
     } 
    } 
+0

मुझे लगता है कि यह स्थिर होना चाहिए –

0

Eren said रूप में, आप ArraySegment<T> उपयोग कर सकते हैं। यहां एक विस्तार विधि और उपयोग उदाहरण है:

public static class ArrayExtensionMethods 
{ 
    public static ArraySegment<T> GetSegment<T>(this T[] arr, int offset, int? count = null) 
    { 
     if (count == null) { count = arr.Length - offset; } 
     return new ArraySegment<T>(arr, offset, count.Value); 
    } 
} 

void Main() 
{ 
    byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; 
    var p1 = arr.GetSegment(0, 5); 
    var p2 = arr.GetSegment(5); 
    Console.WriteLine("First array:"); 
    foreach (byte b in p1) 
    { 
     Console.Write(b); 
    } 
    Console.Write("\n"); 
    Console.WriteLine("Second array:"); 
    foreach (byte b in p2) 
    { 
     Console.Write(b); 
    } 
}