Java可序列化对象到字节数组
假设我有一个可序列化的类Java可序列化对象到字节数组,java,object,serialization,Java,Object,Serialization,假设我有一个可序列化的类AppMessage 我想将它作为byte[]通过套接字传输到另一台机器,在那里它是从接收到的字节重建的 如何实现此目的?准备要发送的字节数组: ByteArrayOutputStream bos=newbytearrayoutputstream(); ObjectOutputStream out=null; 试一试{ out=新对象输出流(bos); out.writeObject(您的对象); out.flush(); byte[]yourBytes=bos.toBy
AppMessage
我想将它作为byte[]
通过套接字传输到另一台机器,在那里它是从接收到的字节重建的
如何实现此目的?准备要发送的字节数组:
ByteArrayOutputStream bos=newbytearrayoutputstream();
ObjectOutputStream out=null;
试一试{
out=新对象输出流(bos);
out.writeObject(您的对象);
out.flush();
byte[]yourBytes=bos.toByteArray();
...
}最后{
试一试{
bos.close();
}捕获(IOEX异常){
//忽略关闭异常
}
}
从字节数组创建对象:
ByteArrayInputStream bis=新的ByteArrayInputStream(字节);
ObjectInput in=null;
试一试{
in=新的ObjectInputStream(bis);
对象o=in.readObject();
...
}最后{
试一试{
if(in!=null){
in.close();
}
}捕获(IOEX异常){
//忽略关闭异常
}
}
最好的方法是使用Apache中的SerializationUtils
要序列化:
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>
org.apache.commons
还有更多提到的方法
或者,可以导入整个集合。请参阅如果使用Java>=7,则可以使用以下方法改进已接受的解决方案:
反过来说:
private Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
如@uris answer中所述,可以通过ApacheUtils的序列化和反序列化方法将对象转换为字节[],反之亦然
要通过序列化将对象转换为字节[],请执行以下操作:
byte[] data = SerializationUtils.serialize(object);
要通过反序列化将字节[]转换为对象,请执行以下操作:
Object object = (Object) SerializationUtils.deserialize(byte[] data)
点击链接到
通过单击以下内容集成.jar文件:
文件名->打开模块设置->选择您的模块->依赖项->添加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();
}
乍一看,您可能认为newbytearrayoutputstream(1024)
只允许固定大小。但是,如果仔细查看ByteArrayOutputStream
,您会发现如果需要,流将增长:
这个类实现了一个输出流,其中的数据是
写入字节数组。缓冲区会随着数据的增长而自动增长
这是写给它的。
可以使用toByteArray()
和
toString()
我想通过套接字将其作为字节[]传输到另一台机器
从接收到的字节中重建
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;
}
}
}
另一个有趣的方法来自com.fasterxml.jackson.databind.ObjectMapper
byte[]data=new ObjectMapper()。writeValueAsBytes(这里是JAVA\u OBJECT\u)
Maven依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
com.fasterxml.jackson.core
杰克逊数据绑定
springframeworkorg.springframework.util.SerializationUtils
byte[] data = SerializationUtils.serialize(obj);
如果您使用的是spring,SpringCore中有一个可用的util类。你可以简单地做
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);
如果你想要一个好的无依赖复制粘贴解决方案。抓取下面的代码
例子
来源
import java.io.*;
公共类序列化{
公共静态字节[]序列化(可序列化值)引发IOException{
ByteArrayOutputStream out=新建ByteArrayOutputStream();
try(ObjectOutputStream outputStream=new ObjectOutputStream(out)){
outputStream.writeObject(值);
}
return out.toByteArray();
}
公共静态T反序列化(字节[]数据)引发IOException,ClassNotFoundException{
try(ByteArrayInputStream bis=新的ByteArrayInputStream(数据)){
//未检查
返回(T)新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 {
}
}
我不是这样理解这个问题的。在我看来,他的问题似乎是如何将对象转换为字节[],而不是如何发送。泰勒:是的,你说得对。我想把这个对象转换成一个字节[]并传输它。请提供有关如何将此字节[]转换为对象的代码。请始终关闭任何流以释放系统资源。(在代码中编辑)这可以处理我无法实现可序列化的对象吗?ObjectInput
、objectOutput
、ByteArrayOutputStream
和ByteArrayInputStream
都实现了自动关闭
接口,使用它来避免错误关闭它们不是一种好的做法吗?(我不完全确定这是否是最佳实践,这就是我想知道的原因。)示例:try(ByteArrayOutputStream bos=newbytearrayoutputstream();ObjectOutput out=newobjectoutputstream(bos)){/*dostuff*/}catch(IOException e){/*抑制异常*/}
。它还消除了对final
子句及其附加的try-catch
的需要。是否增加了开销?最好在这一点上重建车轮。说真的,理解这一行代码和减少可能出现的错误(比如没有在正确的时间关闭流等等)要容易得多。最好的方法是使用一个提供给您的公共库:1)健壮性:人们正在使用它,因此它是有效的。2) 它只需要一行代码就可以完成上面的(最流行的答案),因此代码保持干净。3) 因为丹是这么说的。4) 关于3:-)我只是开玩笑。不幸的是,该方法将输出大小限制为1024。如果需要将文件转换为字节流,最好
byte[] data = SerializationUtils.serialize(obj);
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);
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 {
}
}