修改并重写 json 文件中的密钥
Modify and re-write key from json file
我目前在使用 java 中的 JSON 文件时遇到了一些问题。
这里的目标是将 JSON 文件中的每个“timestamp_ms”修改为 UTC 时间和日期
我的代码输入 JSON 文件,读取它并在最后以我想要的 JSON 格式输出。
然后我遍历所有 timestamp_ms 并转换它们。
我现在想用我得到的输出替换所有 timestamp_ms 并再次将文件重写为 JSON 格式(现在 timestamp_ms 已转换)。
我漫游了 SO 答案,但到目前为止没有成功。任何人都可以知道实现此目标的好方法吗?
代码如下:
public class JsonMain {
public static void main(String[] args) throws IOException {
String first = "chatMessage.json";
String jsonSource = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
//print the json file
System.out.println(jsonSource);
JSONObject obj = new JSONObject(jsonSource);
JSONArray arr = new JSONArray(obj.getJSONArray("messages"));
//iterate trough all the timestamp_ms and get the value
for(int i=0; i< arr.length(); i++)
{
long time = (long)arr.getJSONObject(i).get("timestamp_ms");
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
//arr.put("timestamp_ms",sdf.format(new Date(time)));
}
}
}
这是 json 文件 chatMessage.json
{
"participants": [
{
"name": "User1"
},
{
"name": "User2"
}
],
"messages": [
{
"sender_name": "User1",
"timestamp_ms": 1620663455808,
"content": "Hello ç á à â ã ",
"type": "Generic",
"is_unsent": false
},
{
"sender_name": "User2",
"timestamp_ms": 1620663401347,
"content": "Hi, how are you?",
"type": "Generic",
"is_unsent": false
},
{
"sender_name": "User1",
"timestamp_ms": 1620662999730,
"content": "\u00c3\u0089 to utf?",
"type": "Generic",
"is_unsent": false
}
],
"title": "chatTitle",
"is_still_participant": true,
"thread_type": "RegularGroup",
"thread_path": "inbox/chatTitle_4hyfdfnnhw"
}
你很接近。
只需要引用JSON消息对象而不是数组,然后重写文件。
你可以这样做:
String first = "chatMessage.json";
String jsonSource = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
//print the json file
System.out.println(jsonSource);
JSONObject obj = new JSONObject(jsonSource);
JSONArray arr = new JSONArray(obj.getJSONArray("messages"));
//iterate trough all the timestamp_ms and get the value
for(int i=0; i< arr.length(); i++) {
JSONObject currMessage = arr.getJSONObject(i);
long time = (long) currMessage.get("timestamp_ms");
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
currMessage.put("timestamp_ms", sdf.format(new Date(time)));
}
Files.write(Paths.get(first), obj.toString(2).getBytes());
String output = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
System.out.println(output);
输出:
{
"is_still_participant": true,
"thread_type": "RegularGroup",
"messages": [{
"is_unsent": false,
"sender_name": "User1",
"timestamp_ms": "10.5.2021, 16:17",
"type": "Generic",
"content": "Hello ç á à â ã "
}, {
"is_unsent": false,
"sender_name": "User2",
"timestamp_ms": "10.5.2021, 16:16",
"type": "Generic",
"content": "Hi, how are you?"
}, {
"is_unsent": false,
"sender_name": "User1",
"timestamp_ms": "10.5.2021, 16:09",
"type": "Generic",
"content": "Ã\u0089 to utf?"
}],
"title": "chatTitle",
"thread_path": "inbox/chatTitle_4hyfdfnnhw",
"participants": [{
"name": "User1"
}, {
"name": "User2"
}]
}
我建议使用 token/event/stream-based 解决方案。下面只是使用tiny parser/generator lib https://github.com/anatolygudkov/green-jelly(Gson和Jackson都提供了面向流的API)的说明:
import org.green.jelly.AppendableWriter;
import org.green.jelly.CharArrayCharSequence;
import org.green.jelly.JsonEventPump;
import org.green.jelly.JsonNumber;
import org.green.jelly.JsonParser;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TransformMyJson {
public static void main(String[] args) throws Exception {
try (FileReader input = new FileReader("/home/user/input.json");
FileWriter output = new FileWriter("/home/user/output.json")) {
final JsonParser parser = new JsonParser();
parser.setListener(new MyTransformer(output));
final CharArrayCharSequence charSequence = new CharArrayCharSequence(4096);
final char[] buffer = charSequence.getChars();
int len;
while ((len = input.read(buffer,0, buffer.length)) > -1) {
charSequence.setLength(len);
parser.parse(charSequence);
}
parser.eoj();
}
}
static class MyTransformer extends JsonEventPump {
private final SimpleDateFormat sdf = new SimpleDateFormat();
private boolean isTimestamp;
MyTransformer(final Writer output) {
super(new AppendableWriter<>(output));
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public boolean onObjectMember(final CharSequence name) {
isTimestamp = "timestamp_ms".contentEquals(name);
return super.onObjectMember(name);
}
@Override
public boolean onNumberValue(final JsonNumber number) {
if (isTimestamp) {
return super.onStringValue(sdf.format(new Date(number.mantissa())));
}
return super.onNumberValue(number);
}
}
}
此类解决方案的道具:
- file/data不需要完全加载到内存中,您可以毫无问题地处理megs/gigs
- 它比任何对象映射代码工作得更快,尤其是对于大文件
- 您自然具有与结果相同的 JSON 结构
- 很容易实现任何自定义type/rule 转换
我目前在使用 java 中的 JSON 文件时遇到了一些问题。 这里的目标是将 JSON 文件中的每个“timestamp_ms”修改为 UTC 时间和日期
我的代码输入 JSON 文件,读取它并在最后以我想要的 JSON 格式输出。 然后我遍历所有 timestamp_ms 并转换它们。
我现在想用我得到的输出替换所有 timestamp_ms 并再次将文件重写为 JSON 格式(现在 timestamp_ms 已转换)。 我漫游了 SO 答案,但到目前为止没有成功。任何人都可以知道实现此目标的好方法吗?
代码如下:
public class JsonMain {
public static void main(String[] args) throws IOException {
String first = "chatMessage.json";
String jsonSource = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
//print the json file
System.out.println(jsonSource);
JSONObject obj = new JSONObject(jsonSource);
JSONArray arr = new JSONArray(obj.getJSONArray("messages"));
//iterate trough all the timestamp_ms and get the value
for(int i=0; i< arr.length(); i++)
{
long time = (long)arr.getJSONObject(i).get("timestamp_ms");
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
//arr.put("timestamp_ms",sdf.format(new Date(time)));
}
}
}
这是 json 文件 chatMessage.json
{
"participants": [
{
"name": "User1"
},
{
"name": "User2"
}
],
"messages": [
{
"sender_name": "User1",
"timestamp_ms": 1620663455808,
"content": "Hello ç á à â ã ",
"type": "Generic",
"is_unsent": false
},
{
"sender_name": "User2",
"timestamp_ms": 1620663401347,
"content": "Hi, how are you?",
"type": "Generic",
"is_unsent": false
},
{
"sender_name": "User1",
"timestamp_ms": 1620662999730,
"content": "\u00c3\u0089 to utf?",
"type": "Generic",
"is_unsent": false
}
],
"title": "chatTitle",
"is_still_participant": true,
"thread_type": "RegularGroup",
"thread_path": "inbox/chatTitle_4hyfdfnnhw"
}
你很接近。
只需要引用JSON消息对象而不是数组,然后重写文件。
你可以这样做:
String first = "chatMessage.json";
String jsonSource = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
//print the json file
System.out.println(jsonSource);
JSONObject obj = new JSONObject(jsonSource);
JSONArray arr = new JSONArray(obj.getJSONArray("messages"));
//iterate trough all the timestamp_ms and get the value
for(int i=0; i< arr.length(); i++) {
JSONObject currMessage = arr.getJSONObject(i);
long time = (long) currMessage.get("timestamp_ms");
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
currMessage.put("timestamp_ms", sdf.format(new Date(time)));
}
Files.write(Paths.get(first), obj.toString(2).getBytes());
String output = new String((Files.readAllBytes(Paths.get(first))),"UTF-8");
System.out.println(output);
输出:
{
"is_still_participant": true,
"thread_type": "RegularGroup",
"messages": [{
"is_unsent": false,
"sender_name": "User1",
"timestamp_ms": "10.5.2021, 16:17",
"type": "Generic",
"content": "Hello ç á à â ã "
}, {
"is_unsent": false,
"sender_name": "User2",
"timestamp_ms": "10.5.2021, 16:16",
"type": "Generic",
"content": "Hi, how are you?"
}, {
"is_unsent": false,
"sender_name": "User1",
"timestamp_ms": "10.5.2021, 16:09",
"type": "Generic",
"content": "Ã\u0089 to utf?"
}],
"title": "chatTitle",
"thread_path": "inbox/chatTitle_4hyfdfnnhw",
"participants": [{
"name": "User1"
}, {
"name": "User2"
}]
}
我建议使用 token/event/stream-based 解决方案。下面只是使用tiny parser/generator lib https://github.com/anatolygudkov/green-jelly(Gson和Jackson都提供了面向流的API)的说明:
import org.green.jelly.AppendableWriter;
import org.green.jelly.CharArrayCharSequence;
import org.green.jelly.JsonEventPump;
import org.green.jelly.JsonNumber;
import org.green.jelly.JsonParser;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TransformMyJson {
public static void main(String[] args) throws Exception {
try (FileReader input = new FileReader("/home/user/input.json");
FileWriter output = new FileWriter("/home/user/output.json")) {
final JsonParser parser = new JsonParser();
parser.setListener(new MyTransformer(output));
final CharArrayCharSequence charSequence = new CharArrayCharSequence(4096);
final char[] buffer = charSequence.getChars();
int len;
while ((len = input.read(buffer,0, buffer.length)) > -1) {
charSequence.setLength(len);
parser.parse(charSequence);
}
parser.eoj();
}
}
static class MyTransformer extends JsonEventPump {
private final SimpleDateFormat sdf = new SimpleDateFormat();
private boolean isTimestamp;
MyTransformer(final Writer output) {
super(new AppendableWriter<>(output));
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public boolean onObjectMember(final CharSequence name) {
isTimestamp = "timestamp_ms".contentEquals(name);
return super.onObjectMember(name);
}
@Override
public boolean onNumberValue(final JsonNumber number) {
if (isTimestamp) {
return super.onStringValue(sdf.format(new Date(number.mantissa())));
}
return super.onNumberValue(number);
}
}
}
此类解决方案的道具:
- file/data不需要完全加载到内存中,您可以毫无问题地处理megs/gigs
- 它比任何对象映射代码工作得更快,尤其是对于大文件
- 您自然具有与结果相同的 JSON 结构
- 很容易实现任何自定义type/rule 转换