When the following code is executed, print function prints all the elements within the jsonarray, but the writer, only the first collection of elements.
So far I've tried what is shown in the code, plus, iterating through the list
public class FileWrapper {
public static void WriteRelease(String filename, ArrayList<Object> list) throws IOException, JSONException{
File file = new File(filename);
FileWriter filew = new FileWriter(filename);
JSONArray jsonarray = new JSONArray();
//System.out.println(jsonarray.put(list).toString());
jsonarray.add(list);
System.out.println(jsonarray);
jsonarray.writeJSONString(jsonarray,filew);
filew.close();
}
}
The output I want written in the file is the same as the standard output:
[[Title - Eminem Is Back Status - Bootleg Language - eng
ReleaseDate - 2004-09-28 Format - CD Track Count - 11]] [[Title -
The Eminem Show Status - Official Language - eng ReleaseDate - 2002
Format - Digital Media Track Count - 20]] [[Title - The Eminem Show
Status - Official Language - eng ReleaseDate - 2002 Format -
Digital Media Track Count - 19]]
Again, what is written is only this:
[[Title - Eminem Is Back Status - Bootleg Language - eng
ReleaseDate - 2004-09-28 Format - CD Track Count - 11]]
Turns out, the work around was simple, as noted by #SatyaTNV, the only thing that needed changing was the Filewriter line
By adding
new FileWriter(filename, true)
Everything was printed fine! Thank you based SatyaTNV!
Try this
try (PrintWriter pw = new PrintWriter(writer)) {
pw.println(jsonArray.toString());
}
I am not sure about writing by JSONArray class
Please check my solution:
App.java class
// JSON parser object to parse read file
JSONParser jsonParser = new JSONParser();
try {
URL resource = App.class.getClassLoader().getResource("info.json");
System.out.println(resource.toString());
FileReader reader = new FileReader(resource.getFile());
// Read JSON file
Object obj = jsonParser.parse(reader);
JSONArray infoList = (JSONArray) obj;
System.out.println(infoList);
Information i = new Information();
List<Information> info = i.parseInformationObject(infoList);
saveInformation(info);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
and iterate:
Information.java class
List<Information> parseInformationObject(JSONArray infoList) {
List<Information> in = new ArrayList<>();
infoList.forEach(emp -> {
JSONObject info = (JSONObject) emp;
String id = info.get("id").toString();
String state = info.get("state").toString();
String type = null;
if (info.get("type") != null) {
type = info.get("type").toString();
}
String host = null;
if (info.get("host") != null) {
host = info.get("host").toString();
}
long timestamp = (long) info.get("timestamp");
in.add(new Information(id, state, type, host, timestamp));
});
return in;
}
Related
How to get the first record from a JSON File that contains array of JSON Records
Sample File:
[
{"l7ProtocolID":"dhcp","packets_out":1,"bytes_out":400,"start_time":1454281199898,"flow_sample":0,"duration":102,"path":["base","ip","udp","dhcp"],"bytes_in":1200,"l4":[{"client":"68","server":"67","level":0}],"l2":[{"client":"52:54:00:50:04:B2","server":"FF:FF:FF:FF:FF:FF","level":0}],"l3":[{"client":"::ffff:0.0.0.0","server":"::ffff:255.255.255.255","level":0}],"flow_id":"81454281200000731489","applicationID":"dhcp","packets_in":1}
{"l7ProtocolID":"dhcp","packets_out":1,"bytes_out":400,"start_time":1454281199898,"flow_sample":0,"duration":102,"path":["base","ip","udp","dhcp"],"bytes_in":1200,"l4":[{"client":"68","server":"67","level":0}],"l2":[{"client":"52:54:00:50:04:B2","server":"FF:FF:FF:FF:FF:FF","level":0}],"l3":[{"client":"::ffff:0.0.0.0","server":"::ffff:255.255.255.255","level":0}],"flow_id":"81454281200000731489","applicationID":"dhcp","packets_in":1}
Record n.....
]
And simillarly there might be 1000+ records in the file.
I want to fetch the first record out of this file.
The below code doesn't load the whole file as a String in memory. Although, the whole array would be in memory. For example, Gson would load about 10KB of file bytes into buffer at a time, and parse each row and add to the array. But, all 1000 objects will be on the heap in the array.
Partial Streaming suitable for most cases
public static void readDom() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
Gson gson = new GsonBuilder().create();
Person[] people = gson.fromJson(reader, Person[].class);
System.out.println("Object mode: " + people[0]);
} catch (FileNotFoundException ex) {
...
} finally {
...
}
}
Above code is more efficient than below:
One shot read (Only for small files)
String fileContents = FileUtils.readAsString(file);
Person[] persons = gson.fromJson(fileContents, Person[].class);
First approach could be okay for upto 5k-10k rows at a time. But, beyond 10k, even first approach may not be great.
This third option is the best for large data. Iterate and read one row at a time and stop whenever you want.
True Streaming
public static void readStream() {
try {
JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8"));
Gson gson = new GsonBuilder().create();
// Read file in stream mode
reader.beginArray();
while (reader.hasNext()) {
// Read data into object model
Person person = gson.fromJson(reader, Person.class);
if (person.getId() == 0 ) {
System.out.println("Stream mode: " + person);
}
break;
}
reader.close();
} catch (UnsupportedEncodingException ex) {
...
} catch (IOException ex) {
...
}
}
Source: Reading JSON as Stream using GSON
Dealing with JSON parsing without matching POJO structures
If you don't want to take the trouble of creating a matching POJO object graph structure, you could just instruct GSON to treat each row as a HashMap.
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> thisRow = gson.fromJson(reader, type);
Got the solution using org.JSON.simple library
public String ReadJsonFromFile(String fileName){
JSONParser parser = new JSONParser();
String firstRecord = null;
try {
JSONArray jsonArray = (JSONArray) parser.parse(new FileReader(fileName));
JSONObject jsonObject = (JSONObject) jsonArray.get(0);
firstRecord = jsonObject.toString();
} catch (FileNotFoundException e) {
LOG.info("JSON -> Can't read from file: File Not Found");
e.printStackTrace();
} catch (IOException e) {
LOG.info("JSON -> Can't read File : IO Exception");
e.printStackTrace();
} catch (ParseException e) {
LOG.info("JSON -> Can't Parse JSON in File");
e.printStackTrace();
}
return firstRecord;
}
I’m doing a converter from json to csv file. I’ve tried a solution from this link but it doesn’t work properly: Converting JSON to XLS/CSV in Java
The problem is that I don’t have data in separate columns and also I have names of columns in different order. Is it possible to fix this?
My json looks like this:
{
"Code":2,
"Description":"OK",
"Status":0,
"Items":[{ "City":"nameOfCity",
"Country":"nameOfCountry",
"CountryCode":"US",
"Latitude":"11.11111",
"Longitude":"-11.11111",
"Name":"name of Company",
"Region":"nameofRegion",
"ServisID":"111AAA111AA",
"SiteAddress":"number and street 2301",
"ZipCode":"1111"},
{"City":"nameOfCity2",
"Country":"nameOfCountry",
"CountryCode":"US",
"Latitude":"22.22222",
"Longitude":"22.2222222222",
"Name":"name of Company2",
"Region":"nameofRegion",
"ServisID":"111BBB111BB",
"SiteAddress":null,
"ZipCode":null}
, ...etc.
My code:
String bodyStr = new String(proxyResponse.getBody());
JSONObject output;
try {
output = new JSONObject(bodyStr);
JSONArray docs = output.getJSONArray("Items");
File file = new File("C:/folder/fromJSON.csv");
String csv = CDL.toString(docs);
FileUtils.writeStringToFile(file, csv);
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
results(first expected):
image
working as you expect using the below code. I don't see any major difference between your and my code....
public static void main(String[] args) throws IOException {
String inputJson = "{\"Code\":2,\"Description\":\"OK\",\"Status\":0,\"Items\":[{\"City\":\"nameOfCity\",\"Country\":\"nameOfCountry\",\"CountryCode\":\"US\",\"Latitude\":\"11.11111\",\"Longitude\":\"-11.11111\",\"Name\":\"name of Company\",\"Region\":\"nameofRegion\",\"ServisID\":\"111AAA111AA\",\"SiteAddress\":\"number and street 2301\",\"ZipCode\":\"1111\"},{\"City\":\"nameOfCity2\",\"Country\":\"nameOfCountry\",\"CountryCode\":\"US\",\"Latitude\":\"22.22222\",\"Longitude\":\"22.2222222222\",\"Name\":\"name of Company2\",\"Region\":\"nameofRegion\",\"ServisID\":\"111BBB111BB\",\"SiteAddress\":"
+ null + ",\"ZipCode\":" + null + "}]}";
JSONObject objJsonObject = new JSONObject(inputJson);
JSONArray objJsonArray = objJsonObject.getJSONArray("Items");
String csv = CDL.toString(objJsonArray);
FileUtils.writeStringToFile(new File(System.getenv("HOME")+ "/temp.csv"), csv);
}
i opened the csv file using libreoffice v5.1 with UTF-8 encoding
So I have troubles with creating Json file correctly.
What I have:
1. Gson libs
2. Trying to write in a Json a new user like this:
public static void writeUserBD(String name, String surname, int age) {
//writing in a Json format
JSONObject writeOne = new JSONObject();
JSONArray arr = new JSONArray();
for(int i = 0; i< arr.size() ; i++)
{
writeOne.put("name", name);
writeOne.put("surname", surname);
writeOne.put("age", new Integer(age));
arr.add(writeOne);
writeOne = new JSONObject();
}
//creating dir&file and writing in it
try {
File dir = new File("Test");
dir.mkdir();
File f = new File("Test/TestUser.json");
if (!dir.exists()) {
dir.mkdirs();
} else if (!f.exists()) {
f.createNewFile();
}
//here comes writing encoding problem ! ! !
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f.getAbsoluteFile(), true), Charset.forName("UTF-8")));
try {
bw.write(arr + " " + "\n");
} finally {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
But if I reload my app and try to write a new one it will write a new JSONObject and my output be like :
[{}]
[{}]
In this case i cant parse my json file (for creating simple login) im getting error like "unexcpected token [[]" As I understood this happens becouse of more than 1 jsonobject in a file.
So my question is: how can I write new users data in a json file (even if app was reloaded) in right format that i can pasre than/ for example [{},{},{}]
Try
new FileOutputStream(f.getAbsoluteFile(), false)
true parameter appends to the current file, false should create a new one
The output of your code should be an empty array because you never add an element to the array.
You create a new array and iterate over it. But a new array has no elements and thus the code inside the
loop will never be executed. Beside of that you want to add a new user only once and hence you don't need a loop.
You should read the file first, then add the new user to it and write it back. I created a simple example for you.
I didn't use GSON before, so I'm sure that there is a better way to do this, but it works nevertheless.
I used the try-with-resource feature and the new IO API of Java 7 and did not handle exceptions further. So if you want to handle exceptions
inside the method change the code accordingly. I didn't create the file-structure, so you should do this on your own as well.
public static void writeUserBD(final String name, final String surname, final int age) throws IOException {
final Path jsonFile = Paths.get("Test/TestUser.json");
final JsonArray users = new JsonArray();
// Read all existing users
if (Files.isRegularFile(jsonFile)) {
try (final JsonReader r = new JsonReader(Files.newBufferedReader(jsonFile))) {
r.beginArray();
while (r.hasNext()) {
final JsonObject user = new JsonObject();
r.beginObject();
r.nextName();
user.addProperty("name", r.nextString());
r.nextName();
user.addProperty("surname", r.nextString());
r.nextName();
user.addProperty("age", r.nextInt());
r.endObject();
users.add(user);
}
r.endArray();
}
}
// Create the new user
final JsonObject user = new JsonObject();
user.addProperty("name", name);
user.addProperty("surname", surname);
user.addProperty("age", age);
users.add(user);
// Write all users
try (final BufferedWriter w =
Files.newBufferedWriter(jsonFile, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
w.write(users.toString());
}
}
I want to have a json file like this:
{
"resu0":
{"item":"value"}
"resu1":
{"item":"value"}
"resu2":
{"item":"value"}
}
which "resu" and "0,1,2,..." are came from an intent extra.
And I'm using this code for mu purpose:
private void createsome(String str, int pn, String name,String value){
try {
JSONObject koli = new JSONObject();
JSONObject page = new JSONObject();
page.put(name, value);
koli.put(str + pn, page);
File json = new File(mypath,"myfile.json");
FileWriter jsw = new FileWriter(json);
jsw.write(koli.toString());
jsw.flush();
jsw.close();
} catch (Exception e) {
Log.d("Exxx", e.toString());
}
}
But I' getting just the last one and all new jsonobjects are replacing the previous ones instead of adding. for example if I leave the app when my intent number is "5" my whole jsonfile will be like this:
{
"resu5":
{"item":"value"}
}
I know I have a very small misplace problem but I can't find it.
Change
FileWriter jsw = new FileWriter(json);
with
FileWriter jsw = new FileWriter(json, true);
this way thte FileWriter is opened in append mode
I'm working in my Twitch IRC Bot and we got a Problem.
We receive alot of information through the twitch API (json) like Who followed, dateOf .. viewercounts.. amount of followers and stuff like that.
Were making a Follow-Function to read all the names out of the whole list and set all into our database. First off we tried to just read all and system.output them but we always get the error: org.json.JSONException: JSONArray[100] not found.
We noticed that "0" is holding an array as well so we set the loop to 0-99 and it should change the link then by adding 100+ (next site) and read the JSON again. then it should just continue the loop with the next site.
Below is the Main code as well for the read-methods.
We tried debugging but we wasn't able to find a solution yet x(
MyBot Main Code Snippet:
JSONObject follower = null;
String followername = null;
int listnumber;
offsetvalue = 0;
for(int i = 0; i < TwitchStatus.totalfollows; i++) {
try {
follower = TwitchStatus.followerarray.getJSONObject(i);
} catch (JSONException e2) {
e2.printStackTrace();
}
try {
followername = follower.getJSONObject("user").getString("display_name");
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("array ist: "+i +" " +followername);
listnumber = offsetvalue+99; // 0+99
if (i == listnumber){
offsetvalue = offsetvalue+100;
try {
TwitchStatus.FollowerTicker();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
// System.out.println("Follower abgleichs-Liste: "+followername);
}
And there is the Reader Method:
////////////////////////////////////////////////////////////////////////////////////
// Twitch Follower Ticker
////////////////////////////////////////////////////////////////////////////////////
private String readAll4(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public JSONObject readJsonFromUrl4(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll4(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}
public static void FollowerTicker() throws IOException, JSONException {
json = readJsonFromUrl2("https://api.twitch.tv/kraken/channels/dotastarladder_en/follows?direction=DESC&limit=100&offset="+MyBot.offsetvalue+"");
followerarray = json.getJSONArray("follows");
{
JSONObject follower = followerarray.getJSONObject(0);
neuerfollower = follower.getString("created_at");
fname = follower.getJSONObject("user").getString("display_name");
totalfollows = json.getInt("_total");
}
}
Note from the API docs:
limit optional integer Maximum number of objects in array. Default is 25. Maximum is 100.
So, what do you do? Query the next one, of course! Here's the bit of JSON from the linked page, and an example next URL. Basically, you just put an offset in, but the URL already declares it, so...
{
"_total": 1234,
"_links": {
"next": "https://api.twitch.tv/kraken/channels/test_user1/follows?direction=DESC&limit=25&offset=25",
How I would solve this problem is something like this:
Create an AsyncTask that takes in the URL to parse the JSON text.
When the data has been received, start a new task to read the next one.
Read everything received in this JSON string
Compile everything after it has been downloaded as needed.