직렬화 가능한 클래스가 있다고 가정 해 봅시다 AppMessage
.
byte[]
수신 된 바이트에서 다시 작성되는 다른 컴퓨터에 소켓을 통해 소켓 으로 전송하고 싶습니다 .
어떻게하면 되나요?
new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)
직렬화 가능한 클래스가 있다고 가정 해 봅시다 AppMessage
.
byte[]
수신 된 바이트에서 다시 작성되는 다른 컴퓨터에 소켓을 통해 소켓 으로 전송하고 싶습니다 .
어떻게하면 되나요?
new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)
답변:
전송할 바이트 배열을 준비하십시오.
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
}
}
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
.
가장 좋은 방법 SerializationUtils
은 Apache Commons Lang 에서 사용하는 것입니다 .
직렬화하려면
byte[] data = SerializationUtils.serialize(yourObject);
역 직렬화하려면 다음을 수행하십시오.
YourObject yourObject = SerializationUtils.deserialize(data)
언급했듯이 Commons Lang 라이브러리가 필요합니다. Gradle을 사용하여 가져올 수 있습니다.
compile 'org.apache.commons:commons-lang3:3.5'
메이븐 :
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
또는 전체 컬렉션을 가져올 수 있습니다. 이 링크를 참조하십시오
Java> = 7을 사용하면 try with resources를 사용하여 허용되는 솔루션을 향상시킬 수 있습니다 .
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();
}
}
@uris answer에 명시된 바와 같이 SerializationUtils , ApacheUtils의 직렬화 및 역 직렬화 메소드를 사용하여 객체를 byte []로 변환하거나 그 반대로 변환 할 수 있습니다 .
직렬화하여 객체를 바이트 []로 변환하려면 다음을 수행하십시오.
byte[] data = SerializationUtils.serialize(object);
역 직렬화하여 byte []를 객체로 변환하려면 ::
Object object = (Object) SerializationUtils.deserialize(byte[] data)
org-apache-commons-lang.jar 다운로드 링크를 클릭하십시오
다음을 클릭하여 .jar 파일을 통합하십시오.
FileName- > Open Medule Settings- > 모듈 선택 -> Dependencies- > Jar 파일 추가 가 완료되었습니다.
이것이 도움이되기를 바랍니다 .
SerializationUtils 도구를 사용하는 것이 좋습니다. @ Abilash의 잘못된 의견을 조정하고 싶습니다. 이 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()
.
소켓을 통해 다른 시스템에 byte []로 전송하고 싶습니다.
// 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();
스프링을 사용하는 경우 스프링 코어에서 사용 가능한 util 클래스가 있습니다. 당신은 단순히 할 수 있습니다
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);
Java 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;
}
}
}
의존성이없는 복사 붙여 넣기 솔루션을 원할 경우. 아래 코드를 잡아라.
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();
}
}
}
누구나 프로덕션에서 이것을 사용하려는 경우 허용되는 답변의 최적화 된 코드 형식입니다.
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 {
}
}
byte[]
? 로 소켓에 직접 쓰고 왜ObjectOutputStream
읽지ObjectInputStream
않습니까?