दो byte
सरणियों को सुगम बनाने का आसान तरीका क्या है ?
कहो,
byte a[];
byte b[];
मैं दो byte
सरणियों को कैसे एकत्र करूं और इसे दूसरे byte
सरणी में संग्रहीत करूं?
दो byte
सरणियों को सुगम बनाने का आसान तरीका क्या है ?
कहो,
byte a[];
byte b[];
मैं दो byte
सरणियों को कैसे एकत्र करूं और इसे दूसरे byte
सरणी में संग्रहीत करूं?
जवाबों:
ऐसा करने का सबसे सुंदर तरीका है ByteArrayOutputStream
।
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );
- आपको वापस जाने की ज़रूरत नहीं है और उस पंक्ति को संपादित करें जहां आप परिणाम बाइट सरणी बनाते हैं। एरेस्कोपी विधि का उपयोग करने के विपरीत, सरणियों को फिर से आदेश देना सरल है।
a.length + b.length
तो ByteArrayOutputStream
कंस्ट्रक्टर के लिए तर्क के रूप में उपयोग करना सुनिश्चित करें । ध्यान दें कि यह विधि अभी भी सभी बाइट्स को असाइन करने के लिए एक नए सरणी में कॉपी करेगी c[]
! ByteBuffer
विधि के एक करीबी दावेदार पर विचार करें , जो स्मृति को बर्बाद नहीं करता है।
यहाँ का उपयोग कर एक अच्छा समाधान है अमरूद की com.google.common.primitives.Bytes
:
byte[] c = Bytes.concat(a, b);
इस विधि के बारे में महान बात यह है कि इसमें एक वैरग हस्ताक्षर है:
public static byte[] concat(byte[]... arrays)
जिसका अर्थ है कि आप एक एकल विधि कॉल में मनमाने ढंग से सरणियों को संक्षिप्त कर सकते हैं।
एक और संभावना का उपयोग कर रहा है java.nio.ByteBuffer
।
कुछ इस तरह
ByteBuffer bb = ByteBuffer.allocate(a.length + b.length + c.length);
bb.put(a);
bb.put(b);
bb.put(c);
byte[] result = bb.array();
// or using method chaining:
byte[] result = ByteBuffer
.allocate(a.length + b.length + c.length)
.put(a).put(b).put(c)
.array();
ध्यान दें कि सरणी को शुरू करने के लिए उचित आकार होना चाहिए, इसलिए आवंटन लाइन की आवश्यकता होती है (जैसा कि array()
केवल ऑफसेट, स्थिति या सीमा को ध्यान में रखे बिना बैकिंग सरणी देता है)।
ByteBuffer.allocate(int)
एक स्थिर विधि है जो एक त्वरित java.nio.HeapByteBuffer
, एक उपवर्ग लौटाती है ByteBuffer
। .put()
और .compact()
तरीकों - और किसी भी अन्य अमूर्त सत्ता - का ध्यान रखा जाता है।
compact()
रेखा गलत है।
bb.flip(); bb.get(result);
की जगह में byte[] result = bb.array();
लाइन।
allocate
विधि को सावधानीपूर्वक पढ़ने से निम्नलिखित का पता चलता है: "नई बफर की स्थिति शून्य होगी, इसकी सीमा इसकी क्षमता होगी, इसका निशान अपरिभाषित होगा, और इसके प्रत्येक तत्व को शून्य से प्रारंभ किया जाएगा। । इसमें एक बैकिंग एरे होगा, और इसकी एरे ऑफ़सेट शून्य होगी। " तो कोड के इस विशेष टुकड़े के लिए, जहां ByteBuffer
आंतरिक रूप से आवंटित किया गया है, यह कोई मुद्दा नहीं है।
एक अन्य तरीका एक उपयोगिता फ़ंक्शन का उपयोग करना है (यदि आप चाहें तो आप इसे सामान्य उपयोगिता वर्ग का एक स्थिर तरीका बना सकते हैं):
byte[] concat(byte[]...arrays)
{
// Determine the length of the result array
int totalLength = 0;
for (int i = 0; i < arrays.length; i++)
{
totalLength += arrays[i].length;
}
// create the result array
byte[] result = new byte[totalLength];
// copy the source arrays into the result array
int currentIndex = 0;
for (int i = 0; i < arrays.length; i++)
{
System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length);
currentIndex += arrays[i].length;
}
return result;
}
इस तरह आमंत्रित करें:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
यह 3, 4, 5 सरणियों आदि को समाप्त करने के लिए भी काम करेगा।
इसे इस तरह से करने से आपको तेज एरेस्कोपी कोड का लाभ मिलता है जो पढ़ने और बनाए रखने में भी बहुत आसान है।
byte[] result = new byte[a.length + b.length];
// copy a to result
System.arraycopy(a, 0, result, 0, a.length);
// copy b to result
System.arraycopy(b, 0, result, a.length, b.length);
यदि आप ByteBuffer
@kalefranz को पसंद करते हैं, तो हमेशा byte[]
एक पंक्ति में दो (या इससे भी अधिक) को एक साथ जोड़ने की सकारात्मकता होती है :
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
आप Apache Commons Lang जैसे क्लीन कोड के लिए थर्ड पार्टी लाइब्रेरी का उपयोग कर सकते हैं और इसका उपयोग कर सकते हैं:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)
और byte[] c = Bytes.concat(a, b)
, लेकिन बाद में तेज है।
दो या कई सरणियों के लिए, इस सरल और स्वच्छ उपयोगिता विधि का उपयोग किया जा सकता है:
/**
* Append the given byte arrays to one big array
*
* @param arrays The arrays to append
* @return The complete array containing the appended data
*/
public static final byte[] append(final byte[]... arrays) {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
if (arrays != null) {
for (final byte[] array : arrays) {
if (array != null) {
out.write(array, 0, array.length);
}
}
}
return out.toByteArray();
}
यदि आप दो बाइट सरणियों का विलय कर रहे हैं जिनमें पीडीएफ शामिल है, तो यह तर्क काम नहीं करेगा। हमें अपाचे से पीडीएफबॉक्स जैसे तीसरे पक्ष के उपकरण का उपयोग करने की आवश्यकता है:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();
यदि आप सरणियों के आकार के साथ गड़बड़ नहीं करना चाहते हैं, तो स्ट्रिंग स्ट्रिंग के जादू का उपयोग करें:
byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");
या अपने कोड में कहीं परिभाषित करें
// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;
और उपयोग करें
byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);
यह, निश्चित रूप से, +
अतिरिक्त संचालक का उपयोग करके दो से अधिक स्ट्रिंग संघनन के साथ भी काम करता है ।
दोनों "l1"
और ISO_8859_1
पश्चिमी लैटिन 1 वर्ण सेट को इंगित करते हैं जो प्रत्येक चरित्र को एक बाइट के रूप में एन्कोड करता है। जैसा कि कोई मल्टी-बाइट अनुवाद नहीं किया जाता है, स्ट्रिंग में वर्णों को बाइट्स के समान मान होंगे (सिवाय इसके कि उन्हें हमेशा सकारात्मक मानों के रूप में व्याख्या किया जाएगा, जैसा char
कि अहस्ताक्षरित है)। कम से कम ओरेकल के लिए रनटाइम प्रदान किया जाता है, इसलिए किसी भी बाइट को सही ढंग से "डिकोड किया गया" और फिर "एन्कोडेड" किया जाएगा।
खबरदार कि अतिरिक्त स्मृति की आवश्यकता होती है, तार बाइट सरणी का विस्तार करते हैं। स्ट्रिंग्स को इंटर्न भी किया जा सकता है और इसलिए इसे हटाना आसान नहीं होगा। तार भी अपरिवर्तनीय हैं, इसलिए उनके अंदर के मूल्य नष्ट नहीं हो सकते। इसलिए आपको संवेदनशील सरणियों को इस तरह से परिवर्तित नहीं करना चाहिए और न ही बड़े बाइट सरणियों के लिए इस पद्धति का उपयोग करना चाहिए। आप जो कर रहे हैं उसका एक स्पष्ट संकेत देना भी आवश्यक होगा, क्योंकि सरणी संयोजन का यह तरीका एक सामान्य समाधान नहीं है।
इसे करने का मेरा तरीका है!
public static byte[] concatByteArrays(byte[]... inputs) {
int i = inputs.length - 1, len = 0;
for (; i >= 0; i--) {
len += inputs[i].length;
}
byte[] r = new byte[len];
for (i = inputs.length - 1; i >= 0; i--) {
System.arraycopy(inputs[i], 0, r, len -= inputs[i].length, inputs[i].length);
}
return r;
}
विशेषताएं :
...
किसी भी संख्या के बाइट के साथ बुलाए जाने के लिए varargs ( ) का उपयोग करें []।System.arraycopy()
उच्च गति संचालन सुनिश्चित करने के लिए मशीन विशिष्ट देशी कोड के साथ लागू किया जाता है कि प्रयोग करें ।int
पुन: उपयोग करके थोड़ा कम चर आवंटित करें ।i
len
ध्यान रखें :
ऐसा करने का बेहतर तरीका है, @Jonathan कोड को कॉपी करना । समस्या मूल वैरिएबल सरणियों से आती है, क्योंकि यह डेटा प्रकार किसी अन्य फ़ंक्शन के पास होने पर जावा नए चर बनाता है।
System.arrayCopy
,ByteBuffer
और - तो कुशल लेकिन पढ़ने योग्य नहीं -ByteArrayOutputStream
सभी को कवर किया गया है। हमने यहां दिए गए उत्तरों के 7 से अधिक डुप्लिकेट प्राप्त किए हैं। कृपया कोई और अधिक पोस्ट न करें।