2015-11-02 43 views
3

我想讀對象的序列化的文件,但我想與Java 8的泛函編程功能實驗;但是,我不斷收到一個MalformedInputException。很明顯,Files.lines讀取Stream < String>,而不是對象。 (Files class in Oracle Documentation.)因此,格式錯誤的輸入 - 它不能處理字符串的序列化字符與它使用的字符集。有沒有辦法在Java中讀取使用Files.lines系列化文件8

我通常會使用ObjectInputStream,但我有心情去嘗試新的東西。在Java 8中缺少的東西,允許使用lambdas上下文中的流來讀取序列化文件?

如果您有興趣,這是我在學習它創建流之前所做的嘗試< String>(WordDefinitions。

:基本上只用於實驗的字符串) - 逸是一個序列化的文件從一個類叫我定義保存自定義數據類對象

我甚至嘗試進行明確的轉換:

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

不,你不會錯過任何東西。沒有等效的Files.lines()會返回Stream 。我看到2個主要原因:1.將序列化對象保存在文件中並不常見,應避免IMO(更喜歡更長期的,開放和可維護的解決方案,如JSON或XML),2.將對象保存到使用序列化,序列化單個List或Set對象更容易。 –

+0

謝謝!我很欣賞這些意見。 – jamesc1101

回答

2

沒有這樣的功能,一個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); 
} 
+0

哇!真棒回答!這有很大幫助!我需要一段時間來了解那裏的新概念,但我迫不及待地解決它們!我聽說過Spliterators,但沒有想到他們是什麼或他們是什麼。現在我有一個很好的理由更密切地看待他們。我從來沒有聽說過StreamSupport類!非常感謝您分享您的知識! – jamesc1101

0

號序列化對象沒有行。

+0

是的,我已經想通了這一點,因爲我在我的問題的文本顯示。 JB Nizet回答我的問題非常好 - 「沒有Files.lines(等效),這將返回一個流」。感謝您的時間。 – jamesc1101

相關問題