写入文件时附加 JSONObjects

Appending JSONObjects when writing to a file

我正在尝试将 JSONObjects 附加到名为 Records 的 JSONArray 中。

第一次保存就这样保存了就ok了

{
  "Records": [
    {
      "travelTime": 2,
      "totalDistance": 0,
      "pace": 0,
      "kCalBurned": 0,
      "latlng": "[lat\/lng: (-32.1521234,-63.66412321)]"
    }
  ]
}

但是当我尝试在 Records 中再次追加一个新的 jsonobject 时,它会为其创建一个新的 JSONArray,而我只想在 records 中追加一个新对象

{
  "Records": [
    {
      "travelTime": 2,
      "totalDistance": 0,
      "pace": 0,
      "kCalBurned": 0,
      "latlng": "[lat\/lng: (-31.6432292,-63.3667462)]"
    }
  ]
}{
  "Records": [
    {
      "travelTime": 1,
      "totalDistance": 0,
      "pace": 0,
      "kCalBurned": 0,
      "latlng": "[lat\/lng: (-31.9522431,-64.3461241)]"
    }
  ]
}

这是我用来保存 Records

的代码
   private void writeJsonData(long travelTime,float totalDistance, float pace, float kCalBurned, LinkedList<LatLng> latlng){

        String jsonStr = "";
        JSONObject records  = new JSONObject();
        try {
            records.put("travelTime", travelTime);
            records.put("totalDistance", totalDistance);
            records.put("pace", pace);
            records.put("kCalBurned", kCalBurned);
            records.put("latlng", latlng);

            JSONArray jsonArray = new JSONArray();
            jsonArray.put(records);

            JSONObject recordsObj = new JSONObject();
            recordsObj.put("Records", jsonArray);

            jsonStr = recordsObj.toString();

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String file_name = "records.json";

        FileOutputStream fileOutputStream = null;
        try {

            fileOutputStream = new FileOutputStream(new File(mContext.getFilesDir(),file_name),true);
            fileOutputStream.write(jsonStr.getBytes());
            fileOutputStream.close();


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


    }

您需要一个 JSON 解析器,以便您可以在文件中找到 "Records" 数组并将新数据放在那里。我使用了 "json simple" 库(jar 可以在这里找到:https://code.google.com/archive/p/json-simple/downloads)。

首先你解析文件:

JSONParser parser = new JSONParser();
JSONObject records = null;
try {
    records = (JSONObject) parser.parse(new FileReader("records.json"));
} catch (ParseException ex) {
    ex.printStackTrace();
} catch (IOException ex) {
    ex.printStackTrace();
}

然后找到 Records JSONArray。在那里你想追加新记录:

 JSONArray r = (JSONArray) records.get("Records");

创建新记录:

JSONObject NewObj = new JSONObject();
NewObj.put("travelTime", travelTime);
NewObj.put("totalDistance", totalDistance);
NewObj.put("pace", pace);
NewObj.put("kCalBurned", kCalBurned);
NewObj.put("latlng", latlng);

将新记录添加到 "Records" JSON数组:

r.add(NewObj);

写入文件:

try (FileWriter file = new FileWriter("records.json")) {
     file.write(records.toJSONString());
} catch (IOException ex) {
     ex.printStackTrace();
}

Passing 2nd parameter to true in FileOutputStream constructor will append jsonObject at the end of file.

要在 Records 对象内附加 JSON 数组,您必须先读取文件,附加新的 JSON 对象并将其写回文件。

使用 GSON 库在 java class 和 jSON 之间进行转换。因此,您不必每次都通过放置每个密钥对来手动创建 JSON 对象。

创建一个 Java class 来容纳整个 Records 对象

public class Record
{
    @SerializedName("Records")
    private List<Object> recordsList;

    public Record()
    {
        this. recordsList = new ArrayList<>();
    }

    public List<Object> getRecordsList()
    {
        return recordsList;
    }
}

现在创建JAVA Model class来保存旅行信息

public class Travel {

    private Integer travelTime;
    private Integer totalDistance;
    private Integer pace;
    private Integer kCalBurned;
    private LinkedList<LatLng> latlng;

    public Integer getTravelTime() {
        return travelTime;
    }

    public void setTravelTime(Integer travelTime) {
        this.travelTime = travelTime;
    }

    public Integer getTotalDistance() {
        return totalDistance;
    }

    public void setTotalDistance(Integer totalDistance) {
        this.totalDistance = totalDistance;
    }

    public Integer getPace() {
        return pace;
    }

    public void setPace(Integer pace) {
        this.pace = pace;
    }

    public Integer getKCalBurned() {
        return kCalBurned;
    }

    public void setKCalBurned(Integer kCalBurned) {
        this.kCalBurned = kCalBurned;
    }

    public LinkedList<LatLng> getLatlng() {
        return latlng;
    }

    public void setLatlng(LinkedList<LatLng> latlng) {
        this.latlng = latlng;
    }

}

这是实用程序 class,它具有在 Records 对象中附加新的 JSON 的功能。它将检查目录和文件是否已创建,否则将创建 both.If 文件存在,它将读取文件,将新的 JSON 对象附加到列表并将其写回同一个文件。您可以更改目录和文件名。

注意:这个class是用Kotlin写的。这里是参考 how to setup Android Studio for Kotlin

class Logger {

    companion object {

        private const val LOG_FILE_FOLDER = "Logs"
        private const val LOG_FILE_NAME = "transaction"
        private const val DATE_FORMAT = "yyyy-MM-dd"
        private val logFileName: String
            @SuppressLint("SimpleDateFormat")
            get() {

                var fileName = LOG_FILE_NAME
                val dateFormat = SimpleDateFormat(DATE_FORMAT)
                fileName += "_" + dateFormat.format(Date()) + ".json"
                return fileName
            }

fun logFile(json: Any) {

try {
    val directoryPath = Environment.getExternalStorageDirectory().path + "/" + LOG_FILE_FOLDER
    val loggingDirectoryPath = File(directoryPath)
    var loggingFile = File("$directoryPath/$logFileName")
    if (loggingDirectoryPath.mkdirs() || loggingDirectoryPath.isDirectory) {
        var isFileReady = true
        var isNewFile = false
        if (!loggingFile.exists()) {
            isFileReady = false
            try {
                loggingFile.createNewFile()
                isNewFile = true
                isFileReady = true
            } catch (e: Exception) {
                e.printStackTrace()
            }

        } else {
            val lastFile = getLastFile(loggingFile.name, directoryPath)
            loggingFile = File("$directoryPath/$lastFile")
            val fileSize = getFileSize(loggingFile)

        }
        if (isFileReady) {

            var jsonString: String? = null

            if (!isNewFile) {

                //Get already stored JsonObject
                val stream = FileInputStream(loggingFile)


                try {
                    val fileChannel = stream.channel
                    val mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size())

                    jsonString = Charset.defaultCharset().decode(mappedByteBuffer).toString()
                } catch (e: Exception) {
                    e.printStackTrace()
                } finally {
                    stream.close()
                }
            }


            //Create record object
            val record = if (!jsonString.isNullOrEmpty()) {
                Gson().fromJson(jsonString, Record::class.java)
            } else {
                Record()
            }


            //Append the current json
            record.recordList.add(json)

            //create json to save
            val jsonToSave = Gson().toJson(record)

            val bufferedOutputStream: BufferedOutputStream
            try {
                bufferedOutputStream = BufferedOutputStream(FileOutputStream(loggingFile))
                bufferedOutputStream.write(jsonToSave.toByteArray())
                bufferedOutputStream.flush()
                bufferedOutputStream.close()

            } catch (e4: FileNotFoundException) {
                e4.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                System.gc()
            }
        }
    }
} catch (ex: Exception) {
    ex.printStackTrace()
}
}
}
}

最后可以用logFile方法记录文件

Logger.Companion.logFile(travel);

干杯:)