从文件中读取多个json obj然后将它们推入一个数组并将结果写入文件

时间:2014-12-23 21:56:11

标签: json node.js stream

首先,我是一名前端开发人员,最近我开始学习node.js。

我有多个文件,每个文件都包含一个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文件中。

2 个答案:

答案 0 :(得分: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");

答案 1 :(得分:-1)

我写了一个java转换器(使用jackson库)将文件中的多个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;
      }
  }
}