我正在试验Stanford CoreNLP库,我想序列化主要的StanfordCoreNLP管道对象,尽管它抛出了一个java.io.NotSerializableException。
完整故事:每当我运行我的实现时,将管道注释器和分类器加载到内存中大约需要15秒。最终进程的内存约为600MB(很容易小到可以存储在我的机箱中)。我想在第一次创建管道后保存它,这样我就可以在以后将其读入内存。
然而,它会抛出一个NotSerializableException。我尝试制作一个实现Serializable的简单子类,但StanfordCoreNLP具有不实现此接口的注释器和分类器属性,并且我无法为所有这些创建子类。
有没有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());
}
}
如果它不可序列化的唯一原因是它没有标记为Serializable
,那么您可能可以使用一些非默认的序列化策略。例如,您可以尝试Jackson或XStream。
这就是说,如果一开始就有充分的理由证明它不可序列化,那么这些策略很可能会以有趣的方式崩溃。彻底测试!
一般来说,表示数据对象的Stanford NLP类(Tree、Lce alizedParser等)是可序列化的,而表示处理器的类(StanfordCoreNLP、Lce alizedParserQuery、CRF分类器)则不是。为了实现您的要求,您需要使许多类可序列化,但它们不是,并处理由此产生的任何后果。
然而,我认为你在你的底层思维中是错误的。StanfordCoreNLP在那15秒内加载的东西主要是标准的java序列化对象。NER分类器和解析器语法是标准的序列化java对象。(有几件事不是这种形式的但只是二进制数据,包括用于POS标记器的数据,主要是由于历史原因。)事实是,用标准Java序列化加载很多对象并不是那么快......你可以在网络上找到关于Java序列化速度的讨论,以及替代方案的速度如何比较。制作一个新的甚至更大的序列化对象,其中包含所有当前的序列化对象,这不可能使它更快。(通过将所有内容都放在一个连续的数据流中,您可能会获得一小部分,但除非您做额外的工作来标记不需要序列化的瞬态字段,否则您几乎肯定会因序列化数据结构的大小增加而失败。)
相反,我认为解决这个问题的关键是只需支付加载系统一次的费用,然后在处理多个句子时将其保存在内存中。
本文向大家介绍java对象的序列化和反序列化,包括了java对象的序列化和反序列化的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化 将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化。(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化
问题内容: 我有: 在MyClass2中是无法序列化的属性。如何序列化(和反序列化)此对象? 更正:MyClass2当然不是接口,而是类。 问题答案: 正如其他人指出的那样,Josh Bloch的Effective Java的 第11章是有关Java序列化的必不可少的资源。 该章中与您的问题有关的几点: 假设您要序列化MyClass2中不可序列化字段的状态,则MyClass必须可以直接访问该字段,
问题内容: 如何序列化未实现Serializable的对象?我不能将其标记为Serializable,因为该类来自第3方库。 问题答案: 您不能序列化未实现的类,但可以将其包装在可以实现的类中。为此,您应该在包装器类上实现和,以便可以以自定义方式序列化其对象。 首先,使您的非序列化字段。 在中,首先调用流以存储所有非瞬态字段,然后调用其他方法来序列化不可序列化对象的各个属性。 在中,首先调用流以读
错误: java.lang.ClassNotFoundException:testprocedure.tp$3在java.net.URLClassLoader$1上运行(未知源)在java.net.URLClassLoader上运行(未知源)在java.security.accessController.doprivileged(本机方法)在java.net.URLClassLoader.find
问题内容: 我在android / java中对Location的子类进行序列化遇到了麻烦 位置不可序列化。我有一个名为FALocation的第一个子类,它没有任何实例变量。我已经宣布它可序列化。 然后,我有一个名为Waypoint的第二个类,看起来像这样: 序列化工作正常。 反序列化会产生跟随翼异常(腿对象包含一个航路点): 问题答案: 序列化位置绝对必要吗?也许您可以将其标记为瞬态,并在反序列
如果接口只是一个标记接口,用于在 java 中传递有关类的某种元数据 - 我有点困惑: 在阅读了java的序列化算法(元数据从下到上,然后从上到下的实际实例数据)的过程之后,我无法真正理解哪些数据不能通过该算法进行处理。 简而言之: 哪些数据可能导致? 我怎么知道我不应该为我的类添加子句?