14

I need to read a JSON file in Java with the following structure:

{"id_user":"10","level":"medium","text":"hello 10"}
{"id_user":"20","level":"medium","text":"hello 20"}
{"id_user":"30","level":"medium","text":"hello 30"}

Thanks!.


[POST-EDITED]

I have this code but only read the first JSON Object, I need read the three objects one by one.

private void loadJSONFile(){
        FileReader fileReader = new FileReader(pathFile);
        try (JsonReader jsonReader = new JsonReader(fileReader)) {
            jsonReader.beginObject();
            while (jsonReader.hasNext()) {
                String name = jsonReader.nextName();
                if (name.equals("filter_level")) {
                    System.out.println(jsonReader.nextString());
                } else if (name.equals("text")) {
                    System.out.println("text: " + jsonReader.nextString());
                } else {
                    jsonReader.skipValue();
                }
            }
            jsonReader.endObject();
            jsonReader.close();
        }
    }

thanks!

7
  • 2
    Do you have some code that you've tried, but isn't working? stackoverflow.com/help/how-to-ask Commented Aug 17, 2014 at 5:25
  • Java API for JSON Processing Commented Aug 17, 2014 at 5:31
  • 3
    Side note: That is not valid JSON. Commented Aug 17, 2014 at 5:40
  • 2
    These are 3 different JSON objects. If you are saying a JSON file, then all these objects must be wrapped within a single JSON Object, else it is invalid. Commented Aug 17, 2014 at 7:16
  • 2
    It is absolutely valid to have more than one JSON data structure in one file. The example given is thus legal and any decent JSON parser should be able to read multiple JSON structures from a stream / file / resource. For those who are in doubt - please go ahead and read ECMA-404. Nowhere in this document you will find "file", "resource", "stream", "document" in the context of JSON's data structure notation. Thus the data structure notion is independent of storage questions. Thus you can of course have multiple structures in one file. Period. Commented Feb 14, 2017 at 9:05

10 Answers 10

14

This is a working example based (and tested) with gson-2.8.0. It accepts an arbitrary sequence of JSON objects on a given input stream. And, of course, it does not impose any restrictions on how you have formatted your input:

       InputStream is = /* whatever */
       Reader r = new InputStreamReader(is, "UTF-8");
       Gson gson = new GsonBuilder().create();
       JsonStreamParser p = new JsonStreamParser(r);

       while (p.hasNext()) {
          JsonElement e = p.next();
          if (e.isJsonObject()) {
              Map m = gson.fromJson(e, Map.class);
              /* do something useful with JSON object .. */
          }
          /* handle other JSON data structures */
       }
Sign up to request clarification or add additional context in comments.

Comments

10

I know it has been almost one year for this post :) but i am actually reposing again as an answer because i had this problem same as you Yuan

I have this text.txt file - I know this is not a valid Json array - but if you look, you will see that each line of this file is a Json object in its case alone.

{"Sensor_ID":"874233","Date":"Apr 29,2016 08:49:58 Info Log1"}
{"Sensor_ID":"34234","Date":"Apr 29,2016 08:49:58 Info Log12"}
{"Sensor_ID":"56785","Date":"Apr 29,2016 08:49:58 Info Log13"}
{"Sensor_ID":"235657","Date":"Apr 29,2016 08:49:58 Info Log14"}
{"Sensor_ID":"568678","Date":"Apr 29,2016 08:49:58 Info Log15"}

Now I want to read each line of the above and parse the names "Sensor_ID" and "Date" into Json format. After long search, I have the following:

Try it and look on the console to see the result. I hope it helps.

package reading_file;

import java.io.*;
import java.util.ArrayList;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class file_read {
public static void main(String [] args) {
    ArrayList<JSONObject> json=new ArrayList<JSONObject>();
    JSONObject obj;
    // The name of the file to open.
    String fileName = "C:\\Users\\aawad\\workspace\\kura_juno\\data_logger\\log\\Apr_28_2016\\test.txt ";

    // This will reference one line at a time
    String line = null;

    try {
        // FileReader reads text files in the default encoding.
        FileReader fileReader = new FileReader(fileName);

        // Always wrap FileReader in BufferedReader.
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        while((line = bufferedReader.readLine()) != null) {
            obj = (JSONObject) new JSONParser().parse(line);
            json.add(obj);
            System.out.println((String)obj.get("Sensor_ID")+":"+
                               (String)obj.get("Date"));
        }
        // Always close files.
        bufferedReader.close();         
    }
    catch(FileNotFoundException ex) {
        System.out.println("Unable to open file '" + fileName + "'");                
    }
    catch(IOException ex) {
        System.out.println("Error reading file '" + fileName + "'");                  
        // Or we could just do this: 
        // ex.printStackTrace();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

5 Comments

yes, but you can insert "\r\n" after every writing of the json object in the text.txt file, so you ensure that each line has only one object
The problem is the other way around, if every json is multiple lines.
In this case, i will think about trying to make each json object in exactly one line. coding text line wrapper from "{" to "}" may also be a solution to this issue. I actually have an output json objects file like they are described in the question and i wanted to read them like they are :) that's why i found it useful to post it.
@halim - any arbitrary source code formatter for JSON will make your code break. Would you as customer accept such code? I would not.
yes it is true. this code is only meant too read a file has JSON objects which are saved in a file by the way described above only, if the objects are formatted in different way, it won't work. I am forced to read a JSON objects written in this way by another application. If I can write the JSON objects, I will do them correctly from the beginning.
4

I think what you mean is your Json strings are stored in a text file and you need to read them in to a Json objects. If that's the case use BufferedReader or Scanner to read the file line by line and parse each line to a Json object using json-simple

JsonReader is use to Read One Json Object. Use Scanner or BufferedReader to Read File Line By Line as String and then Parse it to a Json Object.Here is an Example

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class JSONExample{
public static void main(String x[]){
    String FileName="C:\\Users\\Prasad\\Desktop\\JSONExample.txt";
    try {
        ArrayList<JSONObject> jsons=ReadJSON(new File(FileName),"UTF-8");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (ParseException e) {
        e.printStackTrace();
    }
}
public static synchronized ArrayList<JSONObject> ReadJSON(File MyFile,String Encoding) throws FileNotFoundException, ParseException {
    Scanner scn=new Scanner(MyFile,Encoding);
    ArrayList<JSONObject> json=new ArrayList<JSONObject>();
//Reading and Parsing Strings to Json
    while(scn.hasNext()){
        JSONObject obj= (JSONObject) new JSONParser().parse(scn.nextLine());
        json.add(obj);
    }
//Here Printing Json Objects
    for(JSONObject obj : json){
        System.out.println((String)obj.get("id_user")+" : "+(String)obj.get("level")+" : "+(String)obj.get("text"));
    }
    return json;
}

}

2 Comments

yes, i'm using JSON Simple 1.1.1 but i have problems with my code, i edited the original post, can you check the code?, thanks !
@prasadmadanayake - your advice given is very questionable or rather bad practice. Because you rely on the fact that a single line contains a single JSON data structure. Now image what is going to happen if someone is going to format the input? Will such a simple change break your solution?
2

include following maven dependency:

   <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1</version>
    </dependency>

then write your code as below:

public class HistoricalData {
    private static final String PATH = "<PATH>";
    public static void main(String[] args) throws FileNotFoundException,

 ParseException {

    Scanner scanner = new Scanner(new File(PATH + "/Sample.txt"));
    List<JSONObject> jsonArray = new ArrayList<JSONObject>();
    while (scanner.hasNext()) {
        JSONObject obj = (JSONObject) new JSONParser().parse(scanner.nextLine());
        jsonArray.add(obj);
    }
}
}

1 Comment

you also rely on the fact that each JSON structure fits into a single line. Any formatter will break your code.
1

keep the data inside [ ] like [{"id_user":"10","level":"medium","text":"hello 10"} {"id_user":"20","level":"medium","text":"hello 20"} {"id_user":"30","level":"medium","text":"hello 30"}]

inside the file so that it becomes a list then you can use JSONArray . the way I wrote is as follows

public class JSONReadFromFile {

@SuppressWarnings("unchecked")
public static void main(String[] args) {
    JSONParser parser = new JSONParser();

    try {

        Object obj = parser.parse(new FileReader("\\D:\\JSON\\file3.txt"));
        JSONArray jsonArray = (JSONArray) obj;
        int length = jsonArray.size();

        LinkedList author = new LinkedList();


        for (int i =0; i< length; i++) {
            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            Set s = jsonObject.entrySet();
            Iterator iter = s.iterator();

            HashMap hm = new HashMap();

            while(iter.hasNext()){
                Map.Entry me = (Map.Entry) iter.next();
                hm.put(me.getKey(), me.getValue());
            }
            author.add(hm);             
            }            
        for(int i=0;i<author.size();i++){
       HashMap hm = (HashMap) author.get(i);
       Set s = hm.entrySet();
       Iterator iter = s.iterator();
       while(iter.hasNext()){
           Map.Entry me = (Map.Entry) iter.next();
          System.out.println(me.getKey() + "---" + me.getValue());
          }   

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

The output I get is

text---hello 10 id_user---10 level---medium text---hello 20 id_user---20 level---medium text---hello 30 id_user---30 level---medium

3 Comments

you have changed the input like most did. In practice however you have to process a given (!) output, i.e. you have to bite the bullet and process it.
Hi @AMITAVA, i have used your code in my project, and it's working, but it¨s just not outputting in correct order as you see it prints Level medium instead of Id. I tried to fix the bug, but i was unable, i hope you can help fix it. thanks
@Farhad Ba-ali , Hi sorry, I saw this message too late. Anyway for the type of object which contains keys and values, we always get the values by the key. Why the ordering is important here? Anyway I noticed a flaw in my earlier code. We should catch the key,values in a Map instead inside the iterator loop. I edited my answer accordingly.
0

I know two option for read JSON.

JSON Simple its good for small JSON results. But GSON is very usefull for big json results. Because you can set Object form in GSON.

Firs one json.jar

Usage :

String st = ""; // your json object to string
JSONObject newJson = null;
    try {
        newJson = new JSONObject(st);
        newJson.getJSONObject("key");
    } catch (JSONException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

Second One gson.jar

Usage:

int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String anotherStr = gson.fromJson("[\"abc\"]", String.class);

Comments

0

The proper way to work through this JSON file is:

"users": [
  {
    "id_user": "10",
    "level": "medium",
    "text": "hello 10"
  },
  {
    "id_user": "20",
    "level": "medium",
    "text": "hello 20"
  },
  {
    "id_user": "30",
    "level": "medium",
    "text": "hello 30"
  }
]

Try using XStream if you are using a standalone application. It parses JSON into objects in a blink of an eye.

1 Comment

just in case you wonder why no one voted for your "solution": - (a) your example does very obviously NOT contain a legal JSON data structure - (b) - the subject of this question is how to read a given VALID input and not how to read a similar but different input.
0

Using gson to read multiple objects from stream. With gson-2.8.2, I had to call this: reader.setLenient(true);

JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.setLenient(true);
while ((is.available() > 0))
{
    reader.beginObject();
    while (reader.hasNext()) {
        System.out.println("message: "+reader.nextName()+"="+reader.nextString());
    }
    System.out.println("=== End message ===");
    reader.endObject();

This was suggested explicitly by the stack trace, when I did it, the code worked perfectly:

com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 2 column 3481 path $
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1568)
    at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1409)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:542)
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:379)

...

2 Comments

the while (true) loop has me troubled.... How do you know when you are done? Do you catch an exception? Is there a cleaner way?
Ok, there is not while(true). It is while (is.available() > 0), see the variable used to create the JsonReader
0

I used below code and its working fine.

public static void main(String[] args)
        throws IOException, JSchException, SftpException, InterruptedException, ParseException
{
    JSONParser parser = new JSONParser();
    Object obj = parser.parse(new FileReader("c:\\netapp1.txt"));
    Map<Object, Object> shareList = new HashMap<Object, Object>();
    JSONObject jsonObject = (JSONObject) obj;
    JSONArray array = (JSONArray) jsonObject.get("dataLevels"); // it should be any array name

    Iterator<Object> iterator = array.iterator();
    while (iterator.hasNext())
    {
        Object it = iterator.next();
        JSONObject data = (JSONObject) it;
        shareList.put(data.get("name"), data.get("type"));
    }
    Iterator it = shareList.entrySet().iterator();
    while (it.hasNext())
    {
        Map.Entry value = (Map.Entry) it.next();
        System.out.println("Name: " + value.getKey() + " and type: " + value.getValue());
    }
}

JSON:

    {

    "version": 1,

    "dataLevels": 

    [

    {

      "name": "test1",

      "externId": "test1",

      "type": "test1"

    },

    {

      "name": "test2",

      "externId": "test2",

      "type": "test2"

    },

    {

      "name": "test3",

      "externId": "test3",

      "type": "test3"

    }
  ]
}

Comments

-1

My data format is :

"array": [
  {
    "id": "1",
    "name": "peter",
    "text": "hie peter"
  },
  {
    "id": "5",
    "name": "rina",
    "text": "hey rina"
  },
  {
    "id": "12",
    "name": "parx",
    "text": "hey bro"
  }
]

I tried this one and it works :

Object obj = parser.parse(new FileReader("/home/hp2/json.json"));

  JSONObject jsonObject = (JSONObject) obj;
  JSONArray array = (JSONArray) jsonObject.get("array"); // it should be any array name

     Iterator<Object> iterator = array.iterator();
        while (iterator.hasNext()) {
            System.out.println("if iterator have next element " + iterator.next());
        }

1 Comment

This is not a valid JSON data structure and you have the changed the input. Thus you gave an answer for a different problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.