দুটি বাইট অ্যারে সংযুক্ত করার সহজ উপায়


249

দুটি byteঅ্যারে সংযুক্ত করার সহজ উপায় কী ?

বলুন,

byte a[];
byte b[];

আমি কীভাবে দুটি byteঅ্যারে সংযুক্ত করে এটিকে অন্য byteঅ্যারে সঞ্চয় করব?


3
দয়া করে নোট করুন যে অ্যাপাচি কমন্স, গুগলের পেয়ারা System.arrayCopy, ByteBufferএবং - এত দক্ষ নয় তবে পাঠযোগ্য - ByteArrayOutputStreamসবগুলি কভার করা হয়েছে। আমরা এখানে দেওয়া উত্তরের 7 টিরও বেশি ডুপস পেয়েছি। দয়া করে আর কোনও ডুপ পোস্ট করবেন না।
মার্টেন বোদেউয়েস

উত্তর:


316

সবচেয়ে সোজা:

byte[] c = new byte[a.length + b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);

376

এটি করার সর্বাধিক মার্জিত উপায় হ'ল ক ByteArrayOutputStream

byte a[];
byte b[];

ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );

byte c[] = outputStream.toByteArray( );

61
@ ভিআইপউ এটির কারণটি হ'ল কারণ / যদি আপনি পরে কোনও তৃতীয় অ্যারে সংশ্লেষ করতে চান তবে আপনি কেবল লাইনটি যুক্ত করেন outputStream.write( c );- আপনাকে পিছনে গিয়ে লাইনটি সম্পাদন করতে হবে না যেখানে আপনি ফলাফল বাইট অ্যারে তৈরি করেন। এছাড়াও অ্যারেকপি পদ্ধতিটি ব্যবহার না করে অ্যারেগুলিকে পুনরায় অর্ডার করা সহজ।
ওয়েইন উরোদা

2
অতিরিক্ত মাত্র 2 বাইট অ্যারের সাথে কাজ করার সময় এটি আরও সহজ।
gardarh

3
এটি সিপিইউ এবং মেমরি নষ্ট করছে কিনা তা নির্ভর করে আপনি কতবার অপারেশনটি করেন। এটি যদি এক সেকেন্ডে এক বিলিয়ন বার হয় - অবশ্যই, এটি অনুকূলিত করুন। অন্যথায়, পাঠযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতা বিজয়ী বিবেচনা হতে পারে।
ভাইকিংস্টিভ

5
যদি মেমরির খরচ এবং / বা পারফরম্যান্স উদ্বেগজনক হয় a.length + b.lengthতবে ByteArrayOutputStreamকনস্ট্রাক্টরের পক্ষে যুক্তি হিসাবে ব্যবহার করতে ভুলবেন না । নোট করুন যে এই পদ্ধতিটি এখনও নির্ধারণের জন্য সমস্ত বাইটগুলি একটি নতুন অ্যারেতে অনুলিপি করবে c[]! ByteBufferপদ্ধতিটি একটি ঘনিষ্ঠ প্রতিযোগী হিসাবে বিবেচনা করুন , যা স্মৃতিকে নষ্ট করে না।
মার্টেন বোদেউইস

আমি সত্যিই এটিকে থাম্ব দিতে পারি না কারণ এটি কেবল একটি কোড স্নিপেট। এখানে অন্তর্নিহিত টুকরোগুলির কোনও ব্যাখ্যা নেই, যা আমি যত্নশীল সেই অংশটি (এবং আমি মনে করি বেশিরভাগ লোকেরা তা করবে)। যদি সিস্টেম # অ্যারেকপি (অবজেক্ট, ইনট, অবজেক্ট, ইনট, ইনট) এবং বাইটআরআউটআউটপুটস্ট্রিম # পুট (বাইট []) এর মধ্যে পারফরম্যান্স তুলনা হয় এবং উভয় বিকল্পের জন্য কোন দৃশ্যটি সর্বোত্তম হয় তা বিস্তারিতভাবে জানাতে চাই glad এছাড়াও, বলা হচ্ছে যে, উত্তরে অ্যারেকপিও অন্তর্ভুক্ত করা উচিত কারণ এটি অন্য একটি সমাধান।
searchengine27

66

পেয়ারা ব্যবহার করে একটি দুর্দান্ত সমাধান এখানে দেওয়া হয়েছে com.google.common.primitives.Bytes:

byte[] c = Bytes.concat(a, b);

এই পদ্ধতিটি সম্পর্কে দুর্দান্ত বিষয়টি হল এটিতে একটি ভারার্গস স্বাক্ষর রয়েছে:

public static byte[] concat(byte[]... arrays)

যার অর্থ আপনি একক পদ্ধতিতে কলটিতে স্বেচ্ছাসেবী সংখ্যক অ্যারে সংযুক্ত করতে পারেন।


30

আরেকটি সম্ভাবনা ব্যবহার করা হয় 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()কেবলমাত্র ব্যাকিং অ্যারেটি অফসেট, অবস্থান বা সীমা বিবেচনা না করেই ফেরত দেয়)।


3
@ ক্লিক_হির দুঃখিত দুঃখিত, তবে পড়ুনডকস। ByteBuffer.allocate(int)একটি স্থিতিশীল পদ্ধতি যা একটি তাত্ক্ষণিক java.nio.HeapByteBuffer, একটি উপশ্রেণীর ফেরত দেয় ByteBuffer.put()এবং .compact()পদ্ধতি - এবং অন্য কোন বিমূর্ত-অন্তরীপ - যত্ন নেওয়া হয়।
কালেফ্রঞ্জ

@ ক্যালাফ্রানজ compact()লাইনটি ভুল হিসাবে এটি সরানো হয়েছে
মার্টেন বোদেউয়েস

1
বাইটবফারের অ্যারে () পদ্ধতিটি ব্যবহারে যত্ন নিন - আপনি কী করছেন তা পুরোপুরি না জানলে এবং রক্ষণাবেক্ষণ কোনও সমস্যা নয়, এমন কোনও গ্যারান্টি নেই যে বাইটবফারের শূন্যতম অবস্থান সর্বদা বাইট অ্যারের সূচক 0 এর সাথে মিলে যায়। এখানে দেখুন । আমি লাইন bb.flip(); bb.get(result);স্থির করে জারি করে এটি সমাধান byte[] result = bb.array();
ডার্কসান্দু

1
@ ডার্কসান্দু যদিও এটি সাধারণভাবে ভাল পরামর্শ , তবে allocateপদ্ধতির যত্ন সহকারে পড়া নিম্নলিখিত বিষয়গুলি প্রকাশ করে: "নতুন বাফারের অবস্থান শূন্য হবে, এর সীমা তার সক্ষমতা হবে, এর চিহ্নটি অপরিবর্তিত থাকবে এবং এর প্রতিটি উপাদান শূন্যে শুরু করা হবে will এটির একটি ব্যাকিং অ্যারে থাকবে এবং এর অ্যারে অফসেটটি শূন্য হবে। সুতরাং কোডের এই নির্দিষ্ট অংশের জন্য, যেখানে ByteBufferঅভ্যন্তরীণভাবে বরাদ্দ করা হয়, এটি কোনও সমস্যা নয়।
মার্টেন বোদেউয়েস

13

আরেকটি উপায় হ'ল ইউটিলিটি ফাংশনটি ব্যবহার করা (আপনি যদি এটি পছন্দ করেন তবে জেনেরিক ইউটিলিটি শ্রেণির একটি স্ট্যাটিক পদ্ধতি তৈরি করতে পারেন):

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 অ্যারে ইত্যাদির জন্যও কাজ করবে

এটি এইভাবে করা আপনাকে দ্রুত অ্যারেরকপি কোডের সুবিধা দেয় যা পড়া এবং বজায় রাখা খুব সহজ।



11

আপনি যদি ByteBuffer@ কালেফ্রঞ্জের মতো পছন্দ করেন তবে সর্বদা byte[]এক লাইনে দুটি (বা আরও বেশি) সংশ্লেষ করার পক্ষে সম্ভাবনা থাকে :

byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();

এই হিসাবে একই উত্তর কিন্তু 1 বছরের বেশি দেরি। পদ্ধতিতে শৃঙ্খলা ব্যবহার করে তবে বিদ্যমান উত্তরে এটি আরও ভাল করে দেওয়া হবে।
মার্টেন বোদেউয়েস

11

আপনি ক্লিন কোডের জন্য অ্যাপাচি কমন্স ল্যাংয়ের মতো তৃতীয় পক্ষের গ্রন্থাগারগুলি ব্যবহার করতে পারেন এবং এটির মতো ব্যবহার করতে পারেন:

byte[] bytes = ArrayUtils.addAll(a, b);

1
আমি চেষ্টা করেছি ArrayUtils.addAll(a, b)এবং byte[] c = Bytes.concat(a, b), তবে আধুনিকটি আরও দ্রুত।
কার্লোস আন্দ্রেস গার্সিয়া

হতে পারে. আমি পেয়ারা লাইব্রেরি জানি না তাই যদি হয় তবে এটি ব্যবহার করা ভাল। আপনি এটি খুব বড় অ্যারে পরীক্ষা করে দেখেছেন?
টমাসজ প্রিজিবিস্কি

1
আমি যখন পরীক্ষাটি দিয়েছিলাম তখন দ্য ফার্টস অ্যারেটি 68 এলিমেন্ট দৈর্ঘ্যের y দ্বিতীয় 8790688 দৈর্ঘ্যের।
কার্লোস আন্দ্রেস গার্সিয়া

5

দুটি বা একাধিক অ্যারেগুলির জন্য, এই সাধারণ এবং পরিষ্কার ব্যবহারের পদ্ধতিটি ব্যবহার করা যেতে পারে:

/**
 * 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();
}

1
এটি স্মৃতিশক্তি নষ্ট করে। দুটি ছোট অ্যারের জন্য পদ্ধতিটি ঠিক আছে তবে এটি অবশ্যই আরও বেশি অ্যারের জন্য আবর্জনা সংগ্রহকারীকে কর দেবে।
মার্টেন বোদেউয়েস

1

দুটি পিডিএফ বাইট অ্যারে মার্জ করুন

আপনি যদি পিডিএফ সমন্বিত দুটি বাইট অ্যারে মার্জ করে থাকেন তবে এই যুক্তিটি কার্যকর হবে না। আমাদের অ্যাপাচি থেকে পিডিএফক্সবক্সের মতো একটি তৃতীয় পক্ষের সরঞ্জাম ব্যবহার করতে হবে:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();

এই প্রশ্নটি থেকে কিছুটা দূরে, তবে ঠিক আমি যা খুঁজছিলাম।
amos

1

আপনি যদি অ্যারের আকারগুলিতে গণ্ডগোল করতে না চান তবে কেবল স্ট্রিং কনটেনটেশনের যাদুটি ব্যবহার করুন:

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পশ্চিমা লাতিন ১ টি অক্ষর সেটটি নির্দেশ করে যা প্রতিটি অক্ষরকে একক বাইট হিসাবে এনকোড করে। যেহেতু কোনও বহু-বাইট অনুবাদ সম্পাদিত হয় না স্ট্রিংয়ের অক্ষরগুলির বাইটগুলির সমান মান থাকবে (এ ছাড়া তারা সর্বদা ইতিবাচক মান হিসাবে ব্যাখ্যা করা হবে, charস্বাক্ষরবিহীন)। কমপক্ষে ওরাকল প্রদত্ত রানটাইমের জন্য, যে কোনও বাইট সঠিকভাবে "ডিকোডড" হবে এবং তারপরে আবার "এনকোডড" হবে।

সতর্কতা অবলম্বন করুন যে স্ট্রিংগুলি বাইট অ্যারেটি যথেষ্ট পরিমাণে বাড়িয়েছে, অতিরিক্ত মেমরির প্রয়োজন। স্ট্রিংগুলি অভ্যন্তরীণও করা যেতে পারে এবং অতএব সরানো সহজ হবে না। স্ট্রিংগুলিও অপরিবর্তনীয়, তাই তাদের ভিতরে থাকা মানগুলি ধ্বংস করা যায় না। সুতরাং আপনার সংবেদনশীল অ্যারেগুলি এইভাবে জড়িত করা উচিত নয় বা বৃহত্তর বাইট অ্যারেগুলির জন্য আপনার এই পদ্ধতিটি ব্যবহার করা উচিত নয়। আপনি যা করছেন তার একটি স্পষ্ট ইঙ্গিত দেওয়াও প্রয়োজন হবে, কারণ অ্যারে কনটেন্টেশন করার এই পদ্ধতিটি সাধারণ সমাধান নয়।


@ মার্টেনবোডওয়েস যদি আপনি "এল 1" (যা আইএসও 8859-1-এর কেবলমাত্র একটি উপনাম) সম্পর্কে নিশ্চিত না হন তবে "অবশ্যই" শব্দটি ব্যবহার করবেন না। কোন বিশেষ বাইট মানটি মুছে যাবে? মেমোরি ব্যবহারের ক্ষেত্রে, প্রশ্নটি ছিল দুটি বাইট অ্যারে সংমিশ্রণের সহজ উপায় সম্পর্কে, বেশিরভাগ মেমরি দক্ষতার বিষয়ে নয়।
জন ম্যাকক্লেইন

1
আমি কিছু সতর্কতা রেখেছি এবং কিছু পরীক্ষা করেছি। লাতিন 1 এবং ওরাকল প্রদত্ত রানটাইম (11) এর জন্য এটি কার্যকর বলে মনে হচ্ছে না। সুতরাং আমি অতিরিক্ত তথ্য সরবরাহ করেছি এবং আমার মন্তব্য এবং ডাউনভোটটি সরিয়েছি। আমি আশা করি এটি আপনার পক্ষে ঠিক আছে, অন্যথায় দয়া করে ফিরে আসুন।
মার্টেন বোডোয়েস

0

এটি করার আমার উপায়!

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;
}

বৈশিষ্ট্য :

  • যে ...কোনও সংখ্যক বাইটের সাথে কল করতে ভারার্গস ( ) ব্যবহার করুন []।
  • ব্যবহার করুন System.arraycopy()উচ্চ গতির অপারেশন নিশ্চিত করতে যে মেশিন নির্দিষ্ট নেটিভ কোড সঙ্গে বাস্তবায়িত হয়।
  • এটির সঠিক আকারের সাথে একটি নতুন বাইট তৈরি করুন []।
  • একটু কম বরাদ্দ intপুনঃব্যবহার দ্বারা ভেরিয়েবল iএবং lenভেরিয়েবল।
  • ধ্রুবকগুলির সাথে আরও দ্রুত তুলনা।

মনে রাখবেন :

এটি করার সর্বোত্তম উপায় হ'ল @ জোনাথন কোডটি অনুলিপি করুন । সমস্যাটি নেটিভ ভেরিয়েবল অ্যারে থেকে আসে কারণ জাভা নতুন ভেরিয়েবল তৈরি করে যখন এই ডেটা টাইপ অন্য ফাংশনে প্রেরণ করা হয়।


1
না, ওয়েইনের এটি করার উপায় , আপনি 5 বছর দেরী করেছেন।
মার্টেন বোদেউয়েস

@ মার্টেনবোডউয়েস আপনাকে ধন্যবাদ, আমি আজ আপনার কোডিং অনুশীলনের জন্য আপনার মন্তব্যটি ব্যবহার করছি, এখন আরও আলাদা এবং আরও ভাল পারফরম্যান্সের সাথে।
ড্যানিয়েল ডি লিয়ন

1
আমি নিশ্চিত নই যে এটি খুব বেশি পরিমাণে আসবে, এটি দেখে যে অ্যারে মাপগুলি রানটাইমের সময়ও পালটে না, তবে এটি এখন অন্য সমাধান থেকে কমপক্ষে আলাদা।
মার্টেন বোদেউয়েস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.