我将JSONObject保存到磁盘,然后当我尝试将其加载回JSONObject时,在loadSavedScheduleFromDisk方法的这一行出现以下异常:
JSONObject jsonObject = gson.fromJson(reader, JSONObject.class);
com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:第1行第74040列的未终止字符串路径$ .nameValuePairs..values [32] .values [2] .nameValuePairs.disciplineVersionId
这是我的代码:
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();
}
}
这是非常对称的,我不明白为什么它不起作用-我想如果我使用API将我的JSONObject保存到磁盘上并且保存成功,那我怎么不能再加载相同的数据呢? / p>
答案 0 :(得分:1)
我认为问题在于您没有关闭WRITER或默认适配器更改了数据
该错误表明您的JSON严重关闭,可能您的对象未正确压缩或字符串转义不正确
这是我的主张,我的考验通过了我
我创建JSONFileUtil并使用AutoCloseable如果需要关闭流,则最佳实践是使用try-with-resources语句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);
}
}
}
和MyDTO
import java.util.Date;
public class MyDTO {
public String valueString;
public Long valueLong;
public Date valueDate;
}
和我的测试
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
}
}