2016-06-23 49 views
2

我有一串字符串。每個字符串代表像這樣的json對象,例如:java流逗號分隔

// {"foo": "bar", "bar": "foo"} 
String s1 = "{\"foo\": \"bar\", \"bar\": \"foo\"}"; 

我從數據庫中獲取大量數據,這就是爲什麼我使用Stream的原因。 我想將這些數據傳輸到http響應的輸出。

try (Stream<String> data = service.streamData()) { 
      os.write("[".getBytes()); 
      eventStream.forEach(s -> { 
         try { 
          os.write(s.getBytes()); 
          os.write(",".getBytes()); 
          os.write("\n".getBytes()); 
         } catch (IOException e) { 
          logger.error(e.getMessage()); 
         } 
        }); 
     } 
     os.write("{}]".getBytes()); 
     os.flush(); 

由於每個字符串代表一個json對象,我想返回這些對象的數組。在這種情況下,我必須手動添加"[""]",並使用逗號分隔流中的每個元素。但最終我會在最新元素之後留下一個逗號。這不會是一個有效的JSON。

它會是這樣的:

["{"foo": "bar", "bar": "foo"}", "{"foo": "bar1", "bar": "foo1"}",] 

任何想法如何擺脫使用流最新的逗號?

+0

瘸子(但常見的)方法是不在每條消息之後輸出逗號,但在每條消息之前輸出它(除了第一條,可以由布爾值處理)。 – Thilo

+0

另一種蹩腳(但常見)的方法是隻添加一個虛擬條目(假設您可以讓客戶端代碼忽略它)。 – Thilo

+0

Thilo,謝謝你的回答,我有點像你的第一個建議,你能告訴我如何檢查元素是否是第一次,當我用於每個流? – user3127896

回答

2

請注意,雖然lambda表達式是一個整潔的功能,匿名內部類還沒有停止存在。如果你需要一個有狀態的消費者,他們是正確的工具。你甚至都不需要在這裏條件語句:

stream.forEach(new Consumer<String>() { 
    int header = '['; 
    public void accept(String string) { 
     try { 
      os.write(header); 
      os.write('\n'); 
      os.write(string.getBytes(StandardCharsets.UTF_8)); 
      header=','; 
     } catch (IOException e) { 
      logger.error(e.getMessage()); 
     } 
    } 
}); 
os.write('\n'); 
os.write(']'); 

如果你必須處理空流,你可以將它擴展到

os.write('['); 
stream.forEach(new Consumer<String>() { 
    int header = ' '; 
    public void accept(String string) { 
     try { 
      os.write(header); 
      os.write('\n'); 
      os.write(string.getBytes(StandardCharsets.UTF_8)); 
      header=','; 
     } catch (IOException e) { 
      //logger.error(e.getMessage()); 
     } 
    } 
}); 
os.write('\n'); 
os.write(']');