Reputation: 6608
I'm saving my JSONObject to disk and then when I try to load it back to JSONObject, I get the following exception on this line of the loadSavedScheduleFromDisk method:
JSONObject jsonObject = gson.fromJson(reader, JSONObject.class);
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated string at line 1 column 74040 path $.nameValuePairs..values[32].values[2].nameValuePairs.disciplineVersionId
Here is my code:
private void loadSavedScheduleFromDisk(Activity act) {
try {
File file = new File(((Context)act).getCacheDir()+"/"+SCHED_CACHE_FILENAME);
Gson gson = new Gson();
InputStreamReader freader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));
JsonReader reader = new JsonReader(freader);//new FileReader(file));
reader.setLenient(true);
JSONObject jsonObject = gson.fromJson(reader, JSONObject.class);
parseSchedule(jsonObject);
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveScheduleToDisk(Activity act, JSONObject jsonObject )
{
try {
File file = new File(((Context)act).getCacheDir()+"/"+SCHED_CACHE_FILENAME);
//Writer writer = new FileWriter(file);
Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8"));
Gson gson = new GsonBuilder().create();
gson.toJson(jsonObject, writer);
} catch (Exception e) {
e.printStackTrace();
}
}
It is quite symmetrical and I can't understand why it doesn't work - I think if I use API to save my JSONObject to disk and it saves OK, then how come I can't load same data back?
Upvotes: 0
Views: 942
Reputation: 607
I think the problem is that you do not close WRITER or the default adapter change your data
the error indicates that you have a badly closed JSON maybe your object has not been compressed correctly or String escape was incorrect
this is my proposition and my tests pass me
I create JSONFileUtil and I use AutoCloseable If you need to close a stream, then best practice would be to use the try-with-resources statement link
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
public class JSONFileUtil {
public void save(File file, MyDTO myDto) {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8"))) {
writer.write(new Gson().toJson(myDto));
} catch (Exception e) {
e.printStackTrace();
}
}
public MyDTO load(File file) {
try (InputStreamReader freader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"))) {
JsonReader reader = new JsonReader(freader);
return new Gson().fromJson(reader, MyDTO.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
And MyDTO
import java.util.Date;
public class MyDTO {
public String valueString;
public Long valueLong;
public Date valueDate;
}
and my test
import java.io.File;
import java.util.Date;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class JSONFileUtilTest {
@Test
public void saveAndLoad() {
//given:
MyDTO myDTO = new MyDTO();
myDTO.valueString = "aaa";
myDTO.valueLong = 4L;
myDTO.valueDate = new Date(1551427491625L);
File cacheFile = new File("cache" + File.separator + "name.json");
//when:
JSONFileUtil jsonFileUtil = new JSONFileUtil();
jsonFileUtil.save(cacheFile, myDTO);
MyDTO resultMyDto = jsonFileUtil.load(cacheFile);
//then:
assertEquals(myDTO.valueLong, resultMyDto.valueLong); //4
assertEquals(myDTO.valueString, resultMyDto.valueString); // "aaa"
assertEquals(myDTO.valueDate.toString(), resultMyDto.valueDate.toString()); // "Mar 1, 2019 9:04:51 AM" OK
assertNotEquals(myDTO.valueDate.getTime(), resultMyDto.valueDate.getTime()); // it not 1551427491625L but 1551427491000L --> 1551427491625L because the default date format does not store milliseconds
//to store this you need to write your adapter
}
}
Upvotes: 1