gpt4 book ai didi

java - 如何在 Java 中按部分加载序列化对象

转载 作者:行者123 更新时间:2023-11-29 08:51:48 26 4
gpt4 key购买 nike

我正在尝试使用 Externalizable 接口(interface)在 Java 中序列化大型对象。

代码:

public class ResultsData  implements Externalizable{
private static final long serialVersionUID = 1L;

private ArrayList<ALotOfResults1> results1;
private ArrayList<ALotOfResults2> results2;
private ArrayList<ALotOfResults3> results3;

private int selection;

public ResultsData(){

results1=new ArrayList<ALotOfResults1>();
results2=new ArrayList<ALotOfResults2>();
results3=new ArrayList<ALotOfResults3>();

}

//Getter and setter omited

@Override
public void writeExternal(ObjectOutput out) throws IOException {

out.writeObject(results1);
out.writeObject(results2);
out.writeObject(results3);
}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

switch(selection) {
case 0:
results1 = (ArrayList)in.readObject();
break;
case 1:
in.readObject();
results2 = (ArrayList)in.readObject();
break;
case 2:
in.readObject();
in.readObject();
results3 = (ArrayList)in.readObject();
break;
}
}

在程序执行期间填充的那三个数组列表的大小非常大(每个 14 MB)。

代码(加载/保存过程):

public class ResultsManagement {

public static ResultsData loadResultsData(String path,ResultsData resultsData) {

try {

FileInputStream fisProd = new FileInputStream(path+".res");
ObjectInputStream oisProd = new ObjectInputStream(fisProd);
resultsData.readExternal(oisProd);
fisProd.close();

} catch (IOException ioe) {
System.out.println("Error de IO: " + ioe.getMessage());
} catch (ClassNotFoundException cnfe) {
System.out.println("Error de clase no encontrada: " + cnfe.getMessage());
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
return resultsData;
}

public static void saveResultsData(ResultsData resultsData,String path) {
try {
FileOutputStream fosProd = new FileOutputStream(path+".res");
ObjectOutputStream oosProd = new ObjectOutputStream(fosProd);
resultsData.writeExternal(oosProd);
fosProd.close();

} catch (IOException ioe) {
System.out.println("Error de IO: " + ioe.getMessage());
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}

}

不可破解的条件是我只想有一个文件,比如Documents/Project/project1.res

如何在不加载其他部分的情况下加载对象的某些部分?是否可以?例如,当我只需要加载第三个(results3)时,我不需要加载前两个 arrayList(results1 和 results2),但我知道访问 results3 的唯一方法是读取 results1 和 results2。

Tinke 的答案代码:

在 ResultsData 类中:

public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(obj);
return out.toByteArray();
}

public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
return is.readObject();
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {

byte[] r1 = serialize(results1);
System.out.println("Bytes in r1: "+r1.length);//42392 Bytes
out.write(r1);

byte[] r2 = serialize(results2);
System.out.println("Bytes in r2: "+r2.length);//19268558 Bytes (a lot of results here)
out.write(r2);

out.close();

}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

switch(selection) {
case 0:
byte[] arrayBytes=new byte[42392];
in.read(arrayBytes);
results1 = (ArrayList)deserialize(arrayBytes);
break;
case 1:
in.skipBytes(42392);
byte[] arrayBytes2=new byte[19268558];
in.read(arrayBytes2);
results2 = (ArrayList)deserialize(arrayBytes2);
break;
}
}

最佳答案

作为通用解决方案,在插入数据时,插入每个列表的大小(以字节为单位)。然后在阅读时,读入大小并跳过您希望跳过的每个列表的那些字节。该解决方案可以根据您的用例以及您在列表中插入/访问数据的方式进行更多优化。

关于java - 如何在 Java 中按部分加载序列化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22459639/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com