我正在尝试读取对象的序列化文件,但是我想尝试Java 8的功能性编程功能。但是,我一直收到MalformedInputException。显然,Files.lines读取Stream <String>而不是对象。(Oracle文档中的Files类。)因此,格式错误的输入-它无法使用其使用的字符集来处理字符串的序列化字符。
我通常会使用ObjectInputStream,但是我想尝试一些新的东西。我在Java 8中缺少什么可以在lambdas上下文中使用流读取序列化文件的东西吗?
如果您有兴趣,请在尝试创建Stream <String>之前尝试一下(WordDefinitions.dat是一个序列化文件,其中包含来自我称为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
a转换为a的功能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);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句