我有一个JSON文件(myjsonfile.json
),其中将文件夹结构以及文件内容存储为JSON。如下:
{
"name":"folder1",
"type":"directory",
"children":[
{"name":"info",
"type":"directory",
"children": [
{
"name":"info1.txt",
"type":"file",
"content": ["abcd", "efgh", "ijk"]
}]
},
{"name":"data",
"type":"directory",
"children": [{
"name":"data1.txt",
"type":"file",
"content": ["abcd", "xyz"]
}]
}
]
}
我想做的是动态访问两个文本文件(content
或info1.txt
)中的一个的data1.txt
并将其存储为字符串列表。动态是指用户提供文件名,即密钥(info1.txt
或data1.txt
)。
我可以像这样使用org.json
库以静态方式解析和获取值:
File file = new File(myfilepath/myjsonfile.json);
String jsonContent = null;
try {
content = FileUtils.readFileToString(file, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
// Convert JSON string to JSONObject
JSONObject jsonObj = new JSONObject(jsonContent);
JSONArray children = jsonObj.getJSONArray("children");
System.out.println(children.toString());
JSONObject child0 = children.getJSONObject(0);
System.out.println(child0.toString());
// and so on...
但是,我无法弄清楚如何使它动态化,并根据文件名的用户输入将文件内容存储为字符串列表。
有人可以帮我吗?
编辑:澄清了问题。 myfilepath
是指JSON文件(myjsonfile.json
)的文件路径。
答案 0 :(得分:1)
您需要遍历每个对象,并查看name
是否具有您要查找的文件。我建议您使用更详细的JSON处理库(例如Jackson或Gson)使事情变得更容易。但是,考虑到当前的实现方式,您需要按照以下方式进行操作:
if(jsonObj.has("children")) {
JSONArray mainChild = jsonObj.getJSONArray("children");
for(int i=0; i < mainChild.length(); i++) {
if(((JSONObject)mainChild.get(i)).has("children")) {
JSONArray child = ((JSONObject)mainChild.get(i)).getJSONArray("children");
for(int j=0; j < child.length(); j++) {
JSONObject obj = child.getJSONObject(j);
if(obj.has("name")
&& fileNameToLookFor.equals(obj.getString("name"))) {
if(obj.has("content")) {
return obj.getJSONArray("content");
}
return null;
}
}
}
}
return null;
}
答案 1 :(得分:0)
实施自己的tree-node-walker
:
class NodeWalker {
private final JSONObject object;
public NodeWalker(JSONObject object) {
this.object = object;
}
public List<String> findContentFor(String name) {
LinkedList<JSONObject> queue = new LinkedList<>();
queue.add(object);
while (queue.size() > 0) {
JSONObject next = queue.pop();
Object fileName = next.get("name");
final String contentName = "content";
if (fileName != null && fileName.equals(name) && next.has(contentName)) {
JSONArray content = next.getJSONArray(contentName);
if (content == null) {
return Collections.emptyList();
}
List<String> result = new ArrayList<>();
IntStream.range(0, content.length()).forEach(i -> result.add(content.getString(i)));
return result;
}
final String childrenName = "children";
if (next.has(childrenName)) {
JSONArray array = next.getJSONArray(childrenName);
IntStream.range(0, array.length()).forEach(i -> queue.add(array.getJSONObject(i)));
}
}
return Collections.emptyList();
}
}
简单用法:
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;
public class ProfileApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
List<String> strings = Files.readAllLines(jsonFile.toPath());
String json = String.join("", strings);
JSONObject jsonObj = new JSONObject(json);
NodeWalker nodeWalker = new NodeWalker(jsonObj);
String[] files = {"info1.txt", "data1.txt", "data2.txt"};
for (String file : files) {
System.out.println(file + " contents -> " + nodeWalker.findContentFor(file));
}
}
}
打印:
info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []
更容易使用JSON
有效负载的Gson
库和类模型。让我们创建一个类:
class FileNode {
private String name;
private String type;
private List<FileNode> children;
private List<String> content;
public List<String> findContent(String name) {
LinkedList<FileNode> queue = new LinkedList<>();
queue.add(this);
while (queue.size() > 0) {
FileNode next = queue.pop();
if (next.name.equals(name)) {
return next.content;
}
if (next.children != null) {
queue.addAll(next.children);
}
}
return Collections.emptyList();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<FileNode> getChildren() {
return children;
}
public void setChildren(List<FileNode> children) {
this.children = children;
}
public List<String> getContent() {
return content;
}
public void setContent(List<String> content) {
this.content = content;
}
@Override
public String toString() {
return "FileNode{" +
"name='" + name + '\'' +
", type='" + type + '\'' +
", children=" + children +
", content=" + content +
'}';
}
}
我们可以如下使用:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
FileNode root = gson.fromJson(new FileReader(jsonFile), FileNode.class);
String[] files = {"info1.txt", "data1.txt", "data2.txt"};
for (String file : files) {
System.out.println(file + " contents -> " + root.findContent(file));
}
}
}
上面的代码显示:
info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []