जावा क्रमिक वस्तु बाइट ऐरे के लिए


292

मान लीजिए कि मेरे पास एक अनुक्रमिक वर्ग है AppMessage

मैं इसे byte[]दूसरी मशीन पर सॉकेट के रूप में प्रसारित करना चाहता हूं जहां इसे प्राप्त बाइट्स से पुनर्निर्माण किया जाता है।

मैं इसे कैसे हासिल कर सकता हूं?


5
क्यों byte[]? क्यों नहीं इसे सीधे सॉकेट के साथ लिखें ObjectOutputStream, और इसके साथ पढ़ें ObjectInputStream?
लोर्ने जूल का मार्किस

अपाचे ऊंट का उपयोग करें
NOD

1
new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)
असद शकील

जवाबों:


411

भेजने के लिए बाइट सरणी तैयार करें:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
  out = new ObjectOutputStream(bos);   
  out.writeObject(yourObject);
  out.flush();
  byte[] yourBytes = bos.toByteArray();
  ...
} finally {
  try {
    bos.close();
  } catch (IOException ex) {
    // ignore close exception
  }
}

एक बाइट सरणी से एक वस्तु बनाएँ:

ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = null;
try {
  in = new ObjectInputStream(bis);
  Object o = in.readObject(); 
  ...
} finally {
  try {
    if (in != null) {
      in.close();
    }
  } catch (IOException ex) {
    // ignore close exception
  }
}

48
ऐसा नहीं है कि मैंने सवाल कैसे पढ़ा। मेरे लिए यह उनकी समस्या की तरह लग रहा है कि वस्तु को बाइट में कैसे परिवर्तित किया जाए [] - न कि इसे कैसे भेजा जाए।
टेलर लेसे

1
टेलर: हाँ, आपने इसे सही पाया। मैं वस्तु को बाइट में बदलना चाहता हूं [] और इसे प्रसारित करता हूं। क्या आप कृपया इस बाइट को चालू करने के बारे में कोड भी प्रदान कर सकते हैं [] एक वस्तु में कृपया?
ITEgg

कृपया सिस्टम संसाधनों को जारी करने के लिए हमेशा किसी भी स्ट्रीम को बंद करें। (कोड में संपादित)
LuckyMalaka

क्या यह उन वस्तुओं के साथ काम कर सकता है जिन्हें मैं क्रमबद्ध नहीं कर सकता हूं?
KJW

2
ObjectInput, ObjectOuput, ByteArrayOutputStreamऔर ByteArrayInputStreamसभी को लागू AutoCloseableइंटरफेस, यह इसका इस्तेमाल नहीं किया जाएगा अच्छा अभ्यास करने के लिए गलती से उन्हें बंद करने की याद आ रही से बचने के लिए? (मुझे पूरी तरह यकीन नहीं है कि यह सबसे अच्छा अभ्यास है, इसलिए मैं सोच रहा हूं।) उदाहरण try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)){ /*Do stuff*/ }catch(IOException e){/*suppress exception*/}:। यह finalखंड और इसके अतिरिक्त की आवश्यकता को भी हटा देता है try-catch
लुडविग रिडाहल

308

इसका सबसे अच्छा तरीका SerializationUtilsअपाचे कॉमन्स लैंग से उपयोग करना है ।

क्रमबद्ध करने के लिए:

byte[] data = SerializationUtils.serialize(yourObject);

Deserialize करने के लिए:

YourObject yourObject = SerializationUtils.deserialize(data)

जैसा कि उल्लेख किया गया है, इसके लिए कॉमन्स लैंग लाइब्रेरी की आवश्यकता है। यह ग्रेडल का उपयोग करके आयात किया जा सकता है:

compile 'org.apache.commons:commons-lang3:3.5'

Maven:

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.5</version>
</dependency>

जार फ़ाइल

और अधिक तरीके यहां बताए गए हैं

वैकल्पिक रूप से, पूरे संग्रह को आयात किया जा सकता है। इस लिंक को देखें


56
ओवरहेड जोड़ा गया? इस बिंदु पर पहिया का पुनर्निर्माण भी हो सकता है। गंभीरता से, इस एक-लाइनर को समझना और संभावित त्रुटियों को कम करना बहुत आसान है (जैसे सही समय पर स्ट्रीम बंद नहीं करना और क्या नहीं)।
ALOToverflow

2
सबसे अच्छा तरीका है क्योंकि आप एक आम पुस्तकालय की पेशकश करते हैं: 1) मजबूत: लोग इसका उपयोग कर रहे हैं और इस प्रकार यह काम करने के लिए मान्य है। 2) यह ऊपर (सबसे लोकप्रिय उत्तर) केवल 1 लाइन के साथ करता है ताकि आपका कोड साफ रहे। 3) क्योंकि दान ने ऐसा कहा। 4) मैं सिर्फ 3 :-) के बारे में मज़ाक कर रहा हूँ
लॉरेंस

2
दुर्भाग्य से, विधि आउटपुट आकार को 1024 तक सीमित कर देती है। यदि किसी को एक फाइल को बाइट स्ट्रीम में बदलने की आवश्यकता होती है, तो बेहतर है कि इसका उपयोग न करें।
अभिलाष 26:16

मैं इसे माइक्रोसेवर्स के लिए पसंद नहीं करूंगा। प्रत्यक्ष तरीकों की तुलना में पुस्तकालय उन्हें भारी बना सकता है।
ज़ोन

89

यदि आप जावा> = 7 का उपयोग करते हैं, तो आप संसाधनों के साथ प्रयास करके स्वीकृत समाधान में सुधार कर सकते हैं :

private byte[] convertToBytes(Object object) throws IOException {
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
         ObjectOutput out = new ObjectOutputStream(bos)) {
        out.writeObject(object);
        return bos.toByteArray();
    } 
}

और दूसरा तरीका:

private Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
    try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
         ObjectInput in = new ObjectInputStream(bis)) {
        return in.readObject();
    } 
}

7

SerializationUtils द्वारा किया जा सकता है , ApacheUtils द्वारा क्रमबद्ध और deserialize विधि द्वारा वस्तु को बाइट में परिवर्तित करने के लिए [] और इसके विपरीत, जैसा कि @ कानूनी जवाब में कहा गया है।

किसी वस्तु को बाइट में बदलने के लिए [] क्रमबद्ध करके:

byte[] data = SerializationUtils.serialize(object);

बाइट में परिवर्तित करने के लिए [] ऑब्जेक्ट को डिसेरिएलाइजिंग द्वारा ::

Object object = (Object) SerializationUtils.deserialize(byte[] data)

Download org-apache-commons-lang.jar के लिंक पर क्लिक करें

क्लिक करके .jar फ़ाइल को एकीकृत करें:

FileName -> मेड्यूल सेटिंग्स खोलें -> अपने मॉड्यूल का चयन करें -> निर्भरता -> जार फ़ाइल जोड़ें और आप कर रहे हैं।

आशा है कि यह मदद करता है


3
इस तरह एक निर्भरता को कभी न जोड़ें, निर्भरता को डाउनलोड करने के लिए मावेन / ग्रेडेल का उपयोग करें और इसे निर्माण पथ पर जोड़ें
डैनियल बो

4

मैं SerializationUtils टूल का उपयोग करने की भी सलाह देता हूं। मैं @Aililash द्वारा एक गलत टिप्पणी पर अन्याय करना चाहता हूं। SerializationUtils.serialize()विधि है नहीं 1024 बाइट्स, एक और उत्तर यहाँ के विपरीत करने के लिए प्रतिबंधित।

public static byte[] serialize(Object object) {
    if (object == null) {
        return null;
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
    try {
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
        oos.flush();
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
    }
    return baos.toByteArray();
}

पहली नजर में आप सोच सकते हैं कि new ByteArrayOutputStream(1024)केवल एक निश्चित आकार की अनुमति होगी। लेकिन अगर आप इस पर कड़ी नज़र रखते हैं ByteArrayOutputStream, तो आपको पता चलेगा कि यदि आवश्यक हुआ तो धारा बढ़ेगी:

यह वर्ग एक आउटपुट स्ट्रीम को लागू करता है जिसमें डेटा को बाइट सरणी में लिखा जाता है। डेटा के लिखे जाने पर बफ़र अपने आप बढ़ता है। डेटा का उपयोग करके पुनर्प्राप्त किया जा सकता है toByteArray()और toString()


क्या आप रिवर्स कैसे जोड़ सकते हैं? तो बाइट [] आपत्ति करने के लिए? मुझे पता है कि दूसरों के पास यह है, लेकिन मुझे आपका उत्तर बहुत पसंद है और मुझे काम करने के लिए निराशा नहीं मिल सकती है। मैं किसी भी मामले में अशक्त लौटने से बचना चाहता हूं।
तोबियस कोलब

1

मैं इसे बाइट के रूप में [] सॉकेट से दूसरी मशीन पर प्रसारित करना चाहूंगा

// When you connect
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
// When you want to send it
oos.writeObject(appMessage);

जहां इसे प्राप्त बाइट्स से पुनर्निर्माण किया जाता है।

// When you connect
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
// When you want to receive it
AppMessage appMessage = (AppMessage)ois.readObject();

1

एक और दिलचस्प विधि से है com.fasterxml.jackson.databind.ObjectMapper

byte[] data = new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)

मावेन निर्भरता

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

1

स्प्रिंग फ्रेमवर्क org.springframework.util.SerializationUtils

byte[] data = SerializationUtils.serialize(obj);

1

यदि आप स्प्रिंग का उपयोग कर रहे हैं, तो स्प्रिंग-कोर में एक उपयोग वर्ग उपलब्ध है। आप बस कर सकते हैं

import org.springframework.util.SerializationUtils;

byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);

0

जावा 8+ के साथ कोड उदाहरण:

public class Person implements Serializable {

private String lastName;
private String firstName;

public Person() {
}

public Person(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getFirstName() {
    return firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

@Override
public String toString() {
    return "firstName: " + firstName + ", lastName: " + lastName;
}
}


public interface PersonMarshaller {
default Person fromStream(InputStream inputStream) {
    try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
        Person person= (Person) objectInputStream.readObject();
        return person;
    } catch (IOException | ClassNotFoundException e) {
        System.err.println(e.getMessage());
        return null;
    }
}

default OutputStream toStream(Person person) {
    try (OutputStream outputStream = new ByteArrayOutputStream()) {
        ObjectOutput objectOutput = new ObjectOutputStream(outputStream);
        objectOutput.writeObject(person);
        objectOutput.flush();
        return outputStream;
    } catch (IOException e) {
        System.err.println(e.getMessage());
        return null;
    }

}

}

0

मामले में आप एक अच्छा कोई निर्भरता कॉपी पेस्ट समाधान चाहते हैं। नीचे दिए गए कोड को पकड़ो।

उदाहरण

MyObject myObject = ...

byte[] bytes = SerializeUtils.serialize(myObject);
myObject = SerializeUtils.deserialize(bytes);

स्रोत

import java.io.*;

public class SerializeUtils {

    public static byte[] serialize(Serializable value) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try(ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
            outputStream.writeObject(value);
        }

        return out.toByteArray();
    }

    public static <T extends Serializable> T deserialize(byte[] data) throws IOException, ClassNotFoundException {
        try(ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
            //noinspection unchecked
            return (T) new ObjectInputStream(bis).readObject();
        }
    }
}

0

यदि कोई उत्पादन में इसका उपयोग करना चाहता है तो यह स्वीकृत उत्तर का एक अनुकूलित कोड रूप है:

    public static void byteArrayOps() throws IOException, ClassNotFoundException{

    String str="123";
     byte[] yourBytes = null;

    // Convert to byte[]

    try(ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out =  new ObjectOutputStream(bos);) {


      out.writeObject(str);
      out.flush();
      yourBytes = bos.toByteArray();

    } finally {

    }

    // convert back to Object

    try(ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
            ObjectInput in = new ObjectInputStream(bis);) {

      Object o = in.readObject(); 

    } finally {

    }




}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.