首先,我是一名前端开发人员,最近我开始学习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文件中。
答案 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;
}
}
}