gpt4 book ai didi

java - 强制序列化不可序列化的 Java 对象?

转载 作者:搜寻专家 更新时间:2023-10-31 20:22:02 24 4
gpt4 key购买 nike

我正在试验 Stanford CoreNLP 库,我想序列化主要的 StanfordCoreNLP 管道对象,即使它抛出 java.io.NotSerializableException。

全文:每当我运行我的实现时,将管道注释器和分类器加载到内存中大约需要 15 秒。最终进程的内存约为 600MB(小到足以存储在我的案例中)。我想在第一次创建管道后保存它,这样我就可以在之后将它读入内存。

但是它会抛出 NotSerializableException。我尝试创建一个实现 Serializable 的简单子(monad)类,但 StanfordCoreNLP 具有未实现此接口(interface)的注释器和分类器属性,我无法为所有这些创建子类。

是否有任何 Java 库可以序列化未实现 Serializable 的对象?我想它必须递归遍历它的属性并对任何类似的对象执行相同的操作。

我试过的序列化代码:

static StanfordCoreNLP pipeline;
static String file = "/Users/ME/Desktop/pipeline.sav";
static StanfordCoreNLP pipeline() {
if (pipeline == null) {
try {
FileInputStream saveFile = new FileInputStream(file);
ObjectInputStream read = new ObjectInputStream(saveFile);
pipeline = (StanfordCoreNLP) read.readObject();
System.out.println("Pipeline loaded from file.");
read.close();
} catch (FileNotFoundException e) {
System.out.println("Cached pipeline not found. Creating new pipeline...");
Properties props = new Properties();
props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
pipeline = new StanfordCoreNLP(props);
savePipeline(pipeline);
} catch (IOException e) {
System.err.println(e.getLocalizedMessage());
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
}
}
return pipeline;
}

static void savePipeline(StanfordCoreNLP pipeline) {
try {
FileOutputStream saveFile = new FileOutputStream(file);
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(pipeline);
System.out.println("Pipeline saved to file.");
save.close();
} catch (FileNotFoundException e) {
System.out.println("Pipeline file not found during save.");
} catch (IOException e) {
System.err.println(e.getLocalizedMessage());
}
}

最佳答案

一般来说,表示数据对象(Tree、LexicalizedParser 等)的 Stanford NLP 类是可序列化的,而表示处理器的类(StanfordCoreNLP、LexicalizedParserQuery、CRFClassifier)则不是。要实现您的要求,您需要使许多类可序列化,而这些类不是可序列化的,并处理由此产生的任何后果。

但是,我认为您的基本思想是错误的。 StanfordCoreNLP 在这 15 秒内加载的内容主要是标准的 java 序列化对象。 NER 分类器和解析器语法是标准的序列化 java 对象。 (有些东西不是这种形式,而只是二进制数据,包括 POS 标记器,主要是出于历史原因。)事实是,使用标准 Java 序列化加载大量对象并不是那么快......你可以在 Web 上找到有关 Java 序列化速度以及替代方案速度比较的讨论。制作一个包含所有当前序列化对象的新的甚至更大的序列化对象并不能使它更快。 (通过将所有内容都放在一个连续的数据流中,您可能会获得一小部分 yield ,但除非您做额外的工作来标记不需要序列化的 transient 字段,否则您几乎肯定会因序列化数据结构的大小增加而蒙受损失。 )

相反,我建议处理这个问题的关键是付出只加载一次系统的代价,然后在处理很多句子时将其保存在内存中。

关于java - 强制序列化不可序列化的 Java 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12256302/

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