Json is not being written to file - java

I've taken input from editText and trying to write its text to a json file. When I execute the code, it works without any errors. But when I try to read the json file again it doesn't have the previously written objects.
I've tried using different writers like BufferedWriter, FileWriter. None of them works.
This is the writeToJsonFile method
void writeJsonFile(TextView textView) {
String json;
try {
InputStream is = context.getAssets().open("chores.json");
int size = is.available();
byte[] buffer = new byte[size];
if (is.read(buffer) == -1) {
throw new EOFException();
}
is.close();
json = new String(buffer, StandardCharsets.UTF_8);
JSONObject obj = new JSONObject(json);
JSONObject m_jArray = obj.getJSONObject("chores");
JSONArray jsonArray = m_jArray.getJSONArray(title);
JSONObject new_jobj = new JSONObject();
new_jobj.put("task", textView.getText());
new_jobj.put("isCompleted", false);
jsonArray.put(new_jobj);
File file = new File(context.getExternalFilesDir("/assets"), "chores.json");
writeJsonFile(file, obj);
Log.i("Done => ", "Written to file");
} catch (EOFException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This function takes a file and a json object and writes the json object to the file
public static void writeJsonFile(File file, JSONObject json) throws IOException {
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(json.toString());
if (fileWriter != null) {
fileWriter.close();
}
}
I expect it to write the json string to the file, but next time I read the file again with the InputStream, It doesn't show the previously added Object.
expected chores.json
{
"chores": {
"Daily": [
{
"task": "Task 1",
"isCompleted": false
}
],
"Weekly": [
],
"Monthly": [
],
"Custom": [
]
}
}
resulting json
{
"chores": {
"Daily": [
],
"Weekly": [
],
"Monthly": [
],
"Custom": [
]
}
}

You are not writing newly created object into file: For example:
...
JSONObject new_jobj = new JSONObject();
new_jobj.put("task", textView.getText());
new_jobj.put("isCompleted", false);
jsonArray.put(new_jobj);
File file = new File(context.getExternalFilesDir("/assets"), "chores.json");
// here instead of old obj write newly created new_jobj to file.
writeJsonFile(file, new_jobj);
Log.i("Done => ", "Written to file");
...

Before that make sure you have read and write storage permisions....
Ex.
try
{
Writer output = null;
File file = new File("filePath");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
file.createNewFile();
}
output = new BufferedWriter(new FileWriter(file));
output.write(jsonObject.toString());
output.close();
} catch (Exception e) {
e.printStackTrace();
}

You can use the append property in FileWriter constructor. You can try it.
FileWriter fileWriter = new FileWriter(file,true);

Related

JSONWriter add a new Line

I want to write several JSON Objects into a txt-file. For a better view I want that each object is in a different line and there is my problem: I don't know how to add a new line or seperate these objects.
Here is my code:
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("Item", item);
builder.add("Choice 1", idchoice1);
builder.add("Choice 2", idchoice2);
builder.add("Choice 3", idchoice3);
JsonObject jo = builder.build();
try {
FileWriter fw = new FileWriter("SelectedChoice.txt", true);
JsonWriter jsonWriter = Json.createWriter(fw);
jsonWriter.writeObject(jo);
jsonWriter.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
I hope you can help me to solve my problem.
Thanks to everyone!
EDIT:
Now I have seen that this structure in my file doesn't solve my problem.
I want to splitt several JSON Strings which are saved in this txt file and my code only converts the first JSON String in a JSON Object. Here my code:
try {
FileReader fr = new FileReader("SelectedChoice.txt");
BufferedReader br = new BufferedReader(fr);
String zeile ="";
while((zeile = br.readLine())!=null) {
System.out.println(zeile);
JSONObject choice = new JSONObject(zeile);
System.out.println(choice);
}
br.close();
fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I hope you can help me again!
You can use the pretty print option:
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("Item", item);
builder.add("Choice 1", idchoice1);
builder.add("Choice 2", idchoice2);
builder.add("Choice 3", idchoice3);
JsonObject jo = builder.build();
try {
Map<String, Object> properties = new HashMap<>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
FileWriter fw = new FileWriter("SelectedChoice.txt", true);
JsonWriterFactory writerFactory = Json.createWriterFactory(properties);
JsonWriter jsonWriter = writerFactory.createWriter(fw);
jsonWriter.writeObject(jo);
jsonWriter.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}

Create text file and add to zip file and download spring boot with out savind in local server

create and download zip file by adding list of text files. with out creating the file in local server, it should be download at client side direct,
Here i added a code snippet, it was creating in local server, but i dont want that, it should create and download at client side instant. Please help me in this way..
#GetMapping("/download/rawdata")
public void downloadRawdata(#RequestParam("date") String date){
log.info("date : "+date);
List<Rawdata> rawdatas = rawdataRepoisotry.findRawdataByDate(date);
log.info("size of rawdata : "+rawdatas.size());
List<File> files = new ArrayList<File>();
int i = 1;
for(Rawdata rawdata : rawdatas){
log.info("rawdata : "+ rawdata.getRawdata());
File file = new File(i+".txt");
try (Writer writer = new BufferedWriter(new FileWriter(file))) {
String contents = rawdata.getRawdata();
writer.write(contents);
files.add(file);
} catch (IOException e) {
e.printStackTrace();
}
i++;
}
try {
zipFile(files, new File(date+".zip"));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Failed while creating Zip file");
}
}
public FileOutputStream zipFile(final List<File> files, final File targetZipFile) throws IOException {
try {
FileOutputStream fos = new FileOutputStream(targetZipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
byte[] buffer = new byte[128];
for(File currentFile : files){
if (!currentFile.isDirectory()) {
ZipEntry entry = new ZipEntry(currentFile.getName());
FileInputStream fis = new FileInputStream(currentFile);
zos.putNextEntry(entry);
int read = 0;
while ((read = fis.read(buffer)) != -1) {
zos.write(buffer, 0, read);
}
zos.closeEntry();
fis.close();
}
}
zos.close();
fos.close();
return fos;
} catch (FileNotFoundException e) {
System.out.println("File not found : " + e);
throw new FileNotFoundException();
}
}
Here is an example using FileSystemResource.
What has been modified is (see the numbers in the commented code ) :
1) Declare that the response will be of type application/octet-stream
2) #ResponseBody
Annotation that indicates a method return value should be bound to the
web response body
3) Declare that the method returns a FileSystemResource body
4) Return the FileSystemResource entity based on your created zip file
Note that this will still create the file on the server side first, but you may want to use File.createTempFile and File.deleteOnExit.
#GetMapping("/download/rawdata", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)//1
#ResponseBody //2
public ResponseEntity<FileSystemResource> downloadRawdata(#RequestParam("date") String date){ //3
log.info("date : "+date);
List<Rawdata> rawdatas = rawdataRepoisotry.findRawdataByDate(date);
log.info("size of rawdata : "+rawdatas.size());
List<File> files = new ArrayList<File>();
int i = 1;
for(Rawdata rawdata : rawdatas){
log.info("rawdata : "+ rawdata.getRawdata());
File file = new File(i+".txt");
try (Writer writer = new BufferedWriter(new FileWriter(file))) {
String contents = rawdata.getRawdata();
writer.write(contents);
files.add(file);
} catch (IOException e) {
e.printStackTrace();
}
i++;
}
try {
File resultFile = new File(date+".zip");
zipFile(files, resultFile);
return new ResponseEntity<>(new FileSystemResource(resultFile), HttpStatus.OK); //4
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Failed while creating Zip file");
}
}

Copying and appending Strings to json file in Android Studio

I have list of json files as below:
At the moment, T.json file is empty. All the other files already have some text. What I need is to create something like this:
1.At the beginning of the T.json file add sth like
{
"T": [
2.Copy text from e.g. T_Average.json and T_Easy.json to T.json file
3.At the end of T.json file add this:
]
}
So at the end of program execution I need to have in my T.json sth like:
{
"T": [
text from T_Average.json
text from T_Easy.json
]
}
So how can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
I have already tried some solutions like this:
try(FileWriter fw = new FileWriter("T.json", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
out.println("more text");
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
or like this one:
try {
String data = " This is new content";
File file = new File(FILENAME);
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
bw.write(data);
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
but all the time, after line with fw = new FileWriter() it was jumping right to the catch clause.
So one more time:
How can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
Thanks :)
Try
1. Add following methods getJsonFromAssetFile and writeFile to your code
2. Read json file
String content = getJsonFromAssetFile("T_Difficult.json");
3 Create final json (as mentioned)
JSONObject finalJson = new JSONObject();
try {
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonObject);
finalJson.put("T", jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
4. Write final json to file
writeFile(finalJson.toString().getBytes());
writeFile
public static void writeFile(byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getJsonFromAssetFile
public static String getJsonFromAssetFile(Context context, String jsonFileName) {
String json = null;
try {
InputStream is = context.getAssets().open(jsonFileName);
int size = is.available ();
byte[] buffer = new byte[size];
is.read (buffer);
is.close ();
json = new String(buffer, "UTF-8");
}
catch(IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
NOTE: Read json asset file using getJsonFromAssetFile method and Write file on internal/external storage and provide proper path to writeFile method

How to save data with gson in a json file?

In my web application I succeed in displaying data in html table using mybatis. Now I want to save the records of the Mysql table in a json file and create an array of users, I used Gson, the problem is that just one record saved in the file. Thanks.
Here the result in file.json:
{"data":
[
{"id":2,"Name":"Mike"}
]
}
servlet.java
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
for (User u : users) {
Gson gson = new Gson();
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
session.close();
You write all the users in same file C:\\file.json so just the last iteration of the loop saved.
You can convert the object List<User> into json and write it once (no needed loop)
Example:
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson(users, writer);
}
I was previously using outputStream.writeObject and Serializable with default writer/reader for saving object data. Because of problems with code sustainability I have been after something else. This is the result. That BufferedWriter is mandatory, otherwise write speed drops 8 times. Notice that UTF-8 declaration which is default encoding of Json. Not sure whether not declaring it is safe.
Example:
private void saveJson(Object object, Type type, String directory, String fileName) {
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
OutputStream outputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
outputStream = new FileOutputStream(file);
BufferedWriter bufferedWriter;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8));
} else {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
}
gson.toJson(object, type, bufferedWriter);
bufferedWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, IOException e: '" + e + "'");
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(saveJson, "saveUserData, finally, e: '" + e + "'");
}
}
}
}
private Object loadJson(Type type, String directory, String fileName) {
Object jsonData = null;
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
InputStream inputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
inputStream = new FileInputStream(file);
InputStreamReader streamReader;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
} else {
streamReader = new InputStreamReader(inputStream, "UTF-8");
}
jsonData = gson.fromJson(streamReader, type);
streamReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, IOException e: '" + e + "'");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(TAG, "loadJson, finally, e: '" + e + "'");
}
}
}
return jsonData;
}
where Type for example:
Type type = new TypeToken<Map<String, Object>>() { }.getType();
Quick fix to your code:
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
for (User u : users) {
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
However, in the case that your User class looks like this:
public class User {
String id;
String name;
}
Then you don't need to code the adapter as Gson is able to automatically generate the JSON code for a class that only has primitives (ints, Strings, etc.). So your code would look as #roy-shmuli but only if you omit the data and keep only the array as List can be completely generated without an adapter. The JSON code generated would look like this:
[
{"id":1, "name": "Mike"},
{"id":2, "name": "Lucy"}
]
Hope it helps to the beginners.

Extremely weird NullPointerException when reading in a File Android

Here is the code:
Thread clientThread = new Thread() {
#Override
public void run() {
try {
client = new Client();
quest = client.readFile();
Log.v("Client string", quest);
//File file = new File(myContext.getFilesDir(), "questionnaire.xml");
//BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//bw.write(quest);
File tempFile = File.createTempFile("questionnaire", ".xml");
FileOutputStream fout = new FileOutputStream(tempFile);
PrintStream out = new PrintStream(fout);
out.println(quest);//InputStream stream = new ByteArrayInputStream(quest.getBytes("UTF-8"));
//getResources().op
try {
Serializer serializer = new Persister();
responseToQuestionnaire = serializer.read(ResponseToQuestionnaire.class, tempFile);
}
catch(Exception e) {}
Log.v("Let's seeeeee",responseToQuestionnaire.getQuestionnaireTemplate().toString());
} catch (Exception e1) {
e1.printStackTrace();
}
// try {
// OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
// openFileOutput(currentQuestionnaire.getName(),
// Context.MODE_PRIVATE));
// outputStreamWriter.write(client.readFile());
// outputStreamWriter.close();
// } catch (IOException e) {
// Log.e("Exception", "File write failed: " + e.toString());
// }
}
};
clientThread.start();
The code throws a Null Pointer exception even when quest is a full length string that prints in log perfectly fine. I tried multiple ways of saving the file but SimpleXML doesn't serialize string... only XML files.
Buffered streams don't necessarily write the data until they have to. Try closing the output stream before you call the read() method.

Categories