使用多行处理 Json 反序列化

问题描述

我的应用程序期望 Json 文件有两种不同的结构。一个文件,其中每一行是一个完整的 json,另一个文件一个 Json 文件。 例如:一个文件将具有这种结构

package com.example.taskmasterv3; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.room.Dao; import androidx.room.Database; import androidx.room.Delete; import androidx.room.Entity; import androidx.room.Insert; import androidx.room.PrimaryKey; import androidx.room.Query; import androidx.room.Room; import androidx.room.RoomDatabase; import android.content.Intent; import android.database.sqlException; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class SubtaskActivity extends AppCompatActivity { EditText etSubtaskName; EditText etTaskName; Button btnDone,btnCancel; RadioGroup radgrpPri,radgrpTime; RadioButton radbtnPriHigh,radbtnPriMed,radbtnPriLow,radbtnTimeMore,radbtnTimeMed,radbtnTimeLess; boolean priHigh,priMed,priLow,timeMore,timeMed,timeLess; String subtaskName; String pri; String time; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_subtask); btnDone = findViewById(R.id.btnDone); radgrpPri = findViewById(R.id.radgrpPri); radgrpTime = findViewById(R.id.radgrpTime); radbtnPriHigh = findViewById(R.id.radbtnPriHigh); radbtnPriMed = findViewById(R.id.radbtnPriMed); radbtnPriLow = findViewById(R.id.radbtnPriLow); radbtnTimeMore = findViewById(R.id.radbtnTimeMore); radbtnTimeMed = findViewById(R.id.radbtnTimeMed); radbtnTimeLess = findViewById(R.id.radbtnTimeLess); etSubtaskName = findViewById(R.id.etSubtaskName); btnCancel = findViewById(R.id.btnCancel); radgrpPri.setonCheckedchangelistener(new RadioGroup.OnCheckedchangelistener() { @Override public void onCheckedChanged(RadioGroup group,int checkedId) { if (radbtnPriHigh.isChecked()) { priHigh = true; priLow = false; priMed = false; pri = "h"; } else if (radbtnPriMed.isChecked()) { priHigh = false; priLow = false; priMed = true; pri = "m"; } else if (radbtnPriLow.isChecked()) { priHigh = false; priLow = true; priMed = false; pri = "l"; } else { priLow = true; pri = "l"; } } }); radgrpTime.setonCheckedchangelistener(new RadioGroup.OnCheckedchangelistener() { @Override public void onCheckedChanged(RadioGroup group,int checkedId) { if (radbtnTimeMore.isChecked()) { timeMore = true; timeMed = false; timeLess = false; time = "more"; } else if (radbtnTimeMed.isChecked()) { timeMore = false; timeMed = true; timeLess = false; time = "med"; } else if (radbtnTimeLess.isChecked()) { timeMore = false; timeMed = false; timeLess = true; time = "less"; } else { timeLess = true; time = "less"; } } }); btnDone.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String name = etSubtaskName.getText().toString().trim(); Intent intent = new Intent(SubtaskActivity.this,TaskInfo.class); intent.putExtra("subtaskName",name); intent.putExtra("priHigh",priHigh); intent.putExtra("priMed",priMed); intent.putExtra("priLow",priLow); intent.putExtra("timeMore",timeMore); intent.putExtra("timeMed",timeMed); intent.putExtra("timeLess",timeLess); setResult(RESULT_OK,intent); SubtaskActivity.this.finish(); // THIS IS WHERE I SAVE THE DATA IN ROOM AsyncTask.execute(new Runnable() { @Override public void run() { SubtaskDetails subtaskDetails = new SubtaskDetails(etSubtaskName.toString().trim(),pri,time); AppDatabase.getDatabase(getApplicationContext()).userDao().insertAll(subtaskDetails); } }); } }); btnCancel.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { etSubtaskName.setText(""); radgrpPri.clearCheck(); radgrpTime.clearCheck(); finish(); } }); } }

和其他具有这种结构的文件

{"Logging": {"LogLevel": {"Default": "Warning","System": "Warning","Microsoft": "Warning" }}}

我下面的代码进行了反序列化,它适用于第一个结构,但对于其他文件失败,说错误

读取令牌时意外结束。路径''。"}

我的代码

{"Logging": {"LogLevel": {"Default": "Warning","Microsoft": "Warning"
    }}}

我想知道如何解决这个问题,以便它处理这两种类型的文件

解决方法

您正在将 JSON 文件的每一行读入数据变量,试图解析每一行。

因此它尝试解析第 1 行,即 {"Logging": {"LogLevel": {"Default": "Warning",。由于这不是有效的 JSON 对象,解析失败。

改为使用 File.ReadAllText 将整个文件读入单个字符串,然后解析该字符串。或者简单地将字符串数组连接回单个字符串:

 var data = JsonConvert.DeserializeObject<JObject>(string.Join(Environment.NewLine,lines));}