gpt4 book ai didi

serialization - 有没有办法在 Java 8 中使用 Files.lines 读取序列化文件

转载 作者:行者123 更新时间:2023-12-02 01:32:13 25 4
gpt4 key购买 nike

我正在尝试读取对象的序列化文件,但我想试验 Java 8 的函数式编程特性;但是,我一直收到 MalformedInputException。显然,Files.lines 读取的是 Stream ,而不是对象。 ( Files class in Oracle Documentation.) 因此格式错误的输入 -- 它无法使用它使用的字符集处理字符串的序列化字符。

我通常会使用 ObjectInputStream,但我想尝试一些新的东西。 Java 8 中是否缺少允许在 lambda 上下文中使用流读取序列化文件的内容?

如果您有兴趣,这是我在了解到它正在创建 Stream 之前所做的尝试(WordDefinitions.dat 是一个序列化文件,其中包含来 self 称为 Definition 的类的自定义数据类对象——基本上只是字符串实验):

List<Definition> defsList =
Files.lines(Paths.get("WordDefinitions.dat"))
.collect(Collectors.toList());

我什至尝试了显式转换:

List<String> defsList =
Files.lines(Paths.get("WordDefinitions.dat"))
.map(item -> {
Definition temp = (Definition)item;
return temp.toString();
})
.collect(Collectors.toList());

最佳答案

没有这样的功能来转换 ObjectInputStream进入 Stream<Object>通常,这些功能不能很好地协同工作。最值得注意的是,ObjectInputStream不提供任何方法来识别是否有更多对象可用,即是否已到达流的末尾。

不过,您可以使用以下方法创建流:

public static Stream<Object> fromFile(File f) throws IOException {
FileInputStream is=new FileInputStream(f);
try {
ObjectInputStream ois=new ObjectInputStream(is);
return StreamSupport.stream(
new Spliterators.AbstractSpliterator<Object>(Long.MAX_VALUE, Spliterator.ORDERED) {
public boolean tryAdvance(Consumer<? super Object> action) {
try {
action.accept(ois.readObject());
return true;
} catch (IOException ex) {
throw new UncheckedIOException(ex);
} catch (ClassNotFoundException ex) {
throw new NoClassDefFoundError(ex.getMessage());
}
}
@Override public Spliterator<Object> trySplit() { return null; }
}, false).onClose(() -> { try { ois.close(); }
catch (IOException ex) { throw new UncheckedIOException(ex); } });
} catch(Throwable t) {
try(FileInputStream toClose=is) { throw t; }
}
}

如前所述,这个流不知道它的对象数量,因此需要显式使用 limit确保不会尝试读取结尾:

File f=File.createTempFile("ser", null);
try(FileOutputStream os=new FileOutputStream(f);
ObjectOutputStream oos=new ObjectOutputStream(os)) {
oos.writeObject("hello");
oos.writeObject(42);
oos.writeObject(Arrays.asList("X", "Y", "Z"));
oos.flush();
}
System.out.println(f+": "+f.length()+" bytes");
try(Stream<Object> s=fromFile(f)) {
s.limit(3).forEach(System.out::println);
}

关于serialization - 有没有办法在 Java 8 中使用 Files.lines 读取序列化文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33488304/

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