2010-08-04 18 views
9

मैं एक बड़े बाइट सरणी को छोटे हिस्सों में विभाजित करना चाहता हूं (64 बाइट्स कहें)। इसमें मेरी मदद करो।सरणी को छोटे भागों में विभाजित करें

+1

लगता है http://stackoverflow.com/questions/3395547/how-to-get-a-sub-array-of-array-in-java-without-copying-data/ –

उत्तर

14

आप विधि Arrays.copyOfRange (मूल, से, करने के लिए)

public static byte[][] divideArray(byte[] source, int chunksize) { 


     byte[][] ret = new byte[(int)Math.ceil(source.length/(double)chunksize)][chunksize]; 

     int start = 0; 

     for(int i = 0; i < ret.length; i++) { 
      ret[i] = Arrays.copyOfRange(source,start, start + chunksize); 
      start += chunksize ; 
     } 

     return ret; 
    } 

उपयोग कर सकते हैं या के रूप में मैक्स System.arraycopy

public static byte[][] divideArray(byte[] source, int chunksize) { 


     byte[][] ret = new byte[(int)Math.ceil(source.length/(double)chunksize)][chunksize]; 

     int start = 0; 

     for(int i = 0; i < ret.length; i++) { 
      if(start + chunksize > source.length) { 
       System.arraycopy(source, start, ret[i], 0, source.length - start); 
      } else { 
       System.arraycopy(source, start, ret[i], 0, chunksize); 
      } 
      start += chunksize ; 
     } 


     return ret; 
    } 
+0

यह वास्तव में मेरे लिए उपयोगी है। धन्यवाद –

+1

सावधान रहें कि इनमें से दूसरा आखिरी खंड का "बहुत बड़ा" आवंटित प्रतीत होता है यदि स्रोत। लम्बाई chunksize का एक भी बहु नहीं है ... – rogerdpack

0

देखें मदद के लिए Arrays.copyOfRange सुझाव आप उपयोग कर सकते हैं। आप अपने सरणी को कई छोटे हिस्सों में विभाजित करने के लिए इसे लूप में उपयोग कर सकते हैं।

2

ठीक है, System.arraycopy (src, fromPos, dest, toPos, length) को आमतौर पर Arrays.copyOfRange से तेज़ माना जाता है।

byte[] source = ...read it from somewhere...; 
byte[] newArray = new byte[64]; 
System.arraycopy(source, 0, newArray, 0, 64); 
+4

यह गलत है: यह तेजी से होने की बात नहीं है, 'Arrays। copyOfRange' 'System.arraycopy' के दौरान एक नया' सरणी 'आवंटित करता है, केवल पैरामीटर के रूप में पारित किसी अन्य' सरणी 'में तत्वों की प्रतिलिपि बनाएँ। तो दूसरे के साथ आप आवंटन को बचाते हैं .. यही कारण है कि यह तेज़ है। यदि आप 'Array.copyOfRange' की परिभाषा की जांच करते हैं तो आप देखेंगे कि यह' System.arraycopy' 'को आमंत्रित करता है .. – Jack

+0

Yup, अभी चेक किया गया है, आप सही हैं। – bezmax

1

आपके पास दो विकल्प:

  • System.arraycopy(...)
  • Array.copyOfRange(...)

उन दोनों को एक ही तरह से काम करते हैं लेकिन, जबकि पहले एक एकमात्र प्रति प्रबंधन करता है, दूसरा एक करने के लिए है एक ही समय में नए खंड आवंटित करने के लिए प्रयोग किया जाता है।

मैंने उन्हें परिणामस्वरूप बेंचमार्क किया है कि System.arraycopy तेज है यदि आप अपने सरणी को विभाजित करने से पहले सभी को एक साथ आवंटित करने का प्रबंधन करते हैं, लेकिन यदि आप उन्हें कॉपी करते हैं तो थोड़ा धीमा हो: इस मामले में आपको Array.copyOfRange का उपयोग करना चाहिए।

+0

बहुत रोचक बेंचमार्क दिया गया है कि Array.copyOfRange() कॉल सिस्टम System.arraycopy: http://pastebin.com/SpSyx8Cd – bezmax

0

यह करना होगा ...

byte[] source = new byte[2048]; 
    byte[] target = new byte[1024]; 

// fill source with some data... 

    Array.Copy(source, buffer, 1024); 
9

डेमियन Vash की पहली विधि (एक का उपयोग कर Arrays.copyOfRange()) पिछले टुकड़ा के अंत तक शून्य कहते हैं यदि इनपुट बिल्कुल chunksize की एक बहु नहीं है ।

आप बजाय इसका उपयोग करना चाह सकते हैं:

public static List<byte[]> divideArray(byte[] source, int chunksize) { 

    List<byte[]> result = new ArrayList<byte[]>(); 
    int start = 0; 
    while (start < source.length) { 
     int end = Math.min(source.length, start + chunksize); 
     result.add(Arrays.copyOfRange(source, start, end)); 
     start += chunksize; 
    } 

    return result; 
} 

और मामले में यह उपयोगी है, एक ही बात का उपयोग कर ArrayList की:

public static List<List<String>> divideList(List<String> source, int chunksize) { 
    List<List<String>> result = new ArrayList<List<String>>(); 
    int start = 0; 
    while (start < source.size()) { 
     int end = Math.min(source.size(), start + chunksize); 
     result.add(source.subList(start, end)); 
     start += chunksize; 
    } 
    return result; 
    } 
3

आप कुछ स्मृति, एक मामूली संशोधन करने के लिए बचाने के लिए देख रहे हैं दमियन वाश का जवाब मदद करेगा (इस मामले में किसी भी शेष हिस्से को एक पूर्ण 64 बाइट ब्लॉक आकार आवंटित नहीं किया गया है ...)

private byte[][] splitChunks(byte[] source) 
{ 
    byte[][] ret = new byte[(int)Math.ceil(source.length/(double)CHUNK_SIZE)][]; 
    int start = 0; 
    for(int i = 0; i < ret.length; i++) { 
     if(start + CHUNK_SIZE > source.length) { 
      ret[i] = new byte[source.length-start]; 
      System.arraycopy(source, start, ret[i], 0, source.length - start); 
     } 
     else { 
      ret[i] = new byte[CHUNK_SIZE]; 
      System.arraycopy(source, start, ret[i], 0, CHUNK_SIZE); 
     } 
     start += CHUNK_SIZE ; 
    } 
    return ret; 
} 
संबंधित मुद्दे