2014-12-23 141 views
1

首先,我是前端開發人員,最近我開始學習node.js.從文件讀取多個json obj,然後將它們推入一個數組並將結果寫入文件

我有多個文件,每個文件都包含一個json字符串。 在我的節點服務器上,我想讀取這些文件,並將數組中的json對象推送出來,然後我想將結果寫入文件中。

我發現我應該使用節點流。此外,我發現CombinedStream模塊加入文件:

var CombinedStream = require('combined-stream'); 
var request = require("request"); 
var fs = require("fs"); 
var combinedStream = CombinedStream.create(); 

combinedStream.append(request('http://sampledomain/files/file1.json')); 
combinedStream.append(request('http://sampledomain/files/file2.json')); 

combinedStream.pipe(fs.createWriteStream(__dirname + "/output/people.json"); 

我的問題是,我想不出它我怎麼能file1和file2中的內容推到一個數組譜寫people.json文件中的數組。

+1

您是否找到解決方案? –

+1

@master DJon:我把解決方案放在這個repo中https://github.com/Homa/push-json-files-to-an-array – Homa

+0

謝謝,但我沒有找到解決方案。如果你沒有找到一個,我打算幫助你。只是一個想法,你可以通過在文件之前加入'combinedStream.append('[')',...之間加入'append(',')',最後加上'... append(']' )之後? –

回答

-1

我寫了一個java轉換器(使用傑克遜庫)打開多個JSON對象文件到有效的JSON數組:

import java.io.File; 
import com.fasterxml.jackson.core.JsonFactory; 
import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.core.JsonToken; 
import com.fasterxml.jackson.databind.JsonNode; 
import com.fasterxml.jackson.databind.MappingJsonFactory; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.node.ArrayNode; 
import com.fasterxml.jackson.databind.node.JsonNodeFactory; 
import com.fasterxml.jackson.databind.node.ObjectNode; 

public class ParseJson { 
    ObjectMapper mapper = new ObjectMapper(); 

    public static void main(String[] args) throws Exception { 
     File file = new File(args[0]); 
     JsonNode jn = new Parser().parse(file); 

     System.out.println(jn.toString()); 
    } 

    private enum ParserState { 
     start, 
     object, 
     array, 
     field, 
     done 
    }; 

    private static class Parser { 

     public Parser() { 
     } 

     public JsonNode parse(File file) throws Exception { 
      JsonNodeFactory factory = JsonNodeFactory.instance; 
      JsonFactory mappingFactory = new MappingJsonFactory();   
      @SuppressWarnings("deprecation") 
     JsonParser jp = mappingFactory.createJsonParser(file); 

      int n = 0; 
      JsonNode result = null; 
      JsonNode jn; 

      while((jn = parseNode(jp, false)) != null) { 
       if(n == 0) { 
        result = jn; 
       } else if(n == 1) { 
        ArrayNode an = factory.arrayNode(); 
        an.add(result); 
        an.add(jn); 
        result = an; 
       } else if(n > 1) { 
        ArrayNode an = (ArrayNode)result; 
        an.add(jn); 
       } else { 
        throw new Exception("Unexpected parser state"); 
       } 
       n++; 
      } 

      return result; 
     } 

     private JsonNode parseNode(JsonParser jp, boolean current) throws Exception { 
      JsonNodeFactory factory = JsonNodeFactory.instance; 

      ParserState state = ParserState.start; 
      JsonNode result = null; 
      String fieldName = null; 

      JsonToken token = current ? jp.getCurrentToken() : jp.nextToken(); 

      for(; token != null; token = jp.nextToken()) { 

       // System.out.println("Token: "+token+": "+jp.getValueAsString()); 

       switch(token) { 
       /** 
       * NOT_AVAILABLE can be returned if {@link JsonParser} 
       * implementation can not currently return the requested 
       * token (usually next one), or even if any will be 
       * available, but that may be able to determine this in 
       * future. This is the case with non-blocking parsers -- 
       * they can not block to wait for more data to parse and 
       * must return something. 
       */ 
       case NOT_AVAILABLE: { 
        break; 
       } 

       /** 
       * START_OBJECT is returned when encountering '{' 
       * which signals starting of an Object value. 
       */ 
       case START_OBJECT: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.objectNode(); 
          state = ParserState.object; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = parseNode(jp, true); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = parseNode(jp, true); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break;     
       } 

       /** 
       * END_OBJECT is returned when encountering '}' 
       * which signals ending of an Object value 
       */ 
       case END_OBJECT: { 
        switch(state) { 
         case object: { 
          assert result != null; 
          assert fieldName == null; 

          state = ParserState.done; 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break;     
       } 

       /** 
       * START_ARRAY is returned when encountering '[' 
       * which signals starting of an Array value 
       */ 
       case START_ARRAY: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.arrayNode(); 
          state = ParserState.array; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = parseNode(jp, true); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = parseNode(jp, true); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break;     
       } 

       /** 
       * END_ARRAY is returned when encountering ']' 
       * which signals ending of an Array value 
       */ 
       case END_ARRAY: { 
        switch(state) { 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          state = ParserState.done; 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break;     
       } 

       /** 
       * FIELD_NAME is returned when a String token is encountered 
       * as a field name (same lexical value, different function) 
       */ 
       case FIELD_NAME: { 
        fieldName = jp.getValueAsString(); 
        switch(state) { 
         case object: { 
          assert result != null; 
          assert fieldName == null; 

          state = ParserState.field; 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * Placeholder token returned when the input source has a concept 
       * of embedded Object that are not accessible as usual structure 
       * (of starting with {@link #START_OBJECT}, having values, ending with 
       * {@link #END_OBJECT}), but as "raw" objects. 
       *<p> 
       * Note: this token is never returned by regular JSON readers, but 
       * only by readers that expose other kinds of source (like 
       * <code>JsonNode</code>-based JSON trees, Maps, Lists and such). 
       */ 
       case VALUE_EMBEDDED_OBJECT: { 
        throw new Exception("Token not supported: "+token); 
       } 

       /** 
       * VALUE_STRING is returned when a String token is encountered 
       * in value context (array element, field value, or root-level 
       * stand-alone value) 
       */ 
       case VALUE_STRING: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.textNode(jp.getValueAsString()); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.textNode(jp.getValueAsString()); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.textNode(jp.getValueAsString()); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * VALUE_NUMBER_INT is returned when an integer numeric token is 
       * encountered in value context: that is, a number that does 
       * not have floating point or exponent marker in it (consists 
       * only of an optional sign, followed by one or more digits) 
       */ 
       case VALUE_NUMBER_INT: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.numberNode(jp.getLongValue()); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.numberNode(jp.getLongValue()); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.numberNode(jp.getLongValue()); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * VALUE_NUMBER_INT is returned when a numeric token other 
       * that is not an integer is encountered: that is, a number that does 
       * have floating point or exponent marker in it, in addition 
       * to one or more digits. 
       */ 
       case VALUE_NUMBER_FLOAT: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.numberNode(jp.getDoubleValue()); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.numberNode(jp.getDoubleValue()); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.numberNode(jp.getDoubleValue()); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * VALUE_TRUE is returned when encountering literal "true" in 
       * value context 
       */ 
       case VALUE_TRUE: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.booleanNode(true); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.booleanNode(true); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.booleanNode(true); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * VALUE_FALSE is returned when encountering literal "false" in 
       * value context 
       */ 
       case VALUE_FALSE: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.booleanNode(false); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.booleanNode(false); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.booleanNode(false); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       /** 
       * VALUE_NULL is returned when encountering literal "null" in 
       * value context 
       */ 
       case VALUE_NULL: { 
        switch(state) { 
         case start: { 
          assert result == null; 
          assert fieldName == null; 

          result = factory.nullNode(); 
          state = ParserState.done; 
          break; 
         } 
         case field: { 
          assert result != null; 
          assert fieldName != null; 

          ObjectNode on = (ObjectNode)result; 
          JsonNode jn = factory.nullNode(); 
          on.set(fieldName, jn); 
          fieldName = null; 
          state = ParserState.object; 
          break; 
         } 
         case array: { 
          assert result != null; 
          assert fieldName == null; 

          ArrayNode an = (ArrayNode)result; 
          JsonNode jn = factory.nullNode(); 
          an.add(jn); 
          break; 
         } 
         default: { 
          throw new Exception("Unexpected state: "+state+", for token: "+token); 
         } 
        } 

        break; 
       } 

       default: { 
        throw new Exception("Token not supported: "+token); 
       } 

       } 

       if(state == ParserState.done) { 
        break; 
       } 
      }   

      return result; 
     } 
    } 
} 
1

這裏是你已經開始什麼的完成。我添加了將這些JSON對象放入數組所需的內容。

var CombinedStream = require('combined-stream'); 
var request = require("request"); 
var fs = require("fs"); 
var combinedStream = CombinedStream.create(); 
var files = ['http://sampledomain/files/file1.json', 'http://sampledomain/files/file2.json']; 

combinedStream.append('['); 
for(var i = 0; i < files.length; i++) { 
    if (i != 0) combinedStream.append(','); 
    combinedStream.append(request(files[i])); 
} 
combinedStream.append(']'); 
combinedStream.pipe(fs.createWriteStream(__dirname + "/output/people.json"); 
+0

@霍馬你應該接受一個答案,當它適合你的問題。 –

相關問題