สมมติว่าฉันมีไฟล์ที่มีเนื้อหา JSON อยู่ในโฟลเดอร์ทรัพยากรดิบในแอปของฉัน ฉันจะอ่านสิ่งนี้ในแอปได้อย่างไรจึงจะสามารถแยกวิเคราะห์ JSON ได้
สมมติว่าฉันมีไฟล์ที่มีเนื้อหา JSON อยู่ในโฟลเดอร์ทรัพยากรดิบในแอปของฉัน ฉันจะอ่านสิ่งนี้ในแอปได้อย่างไรจึงจะสามารถแยกวิเคราะห์ JSON ได้
คำตอบ:
ดูopenRawResource สิ่งนี้ควรใช้งานได้:
InputStream is = getResources().openRawResource(R.raw.json_file);
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
String jsonString = writer.toString();
\res\json_file.json
โฟลเดอร์หรือภายใน\res\raw\json_file.json
?
getResources()
เรียกได้ว่าอยู่ที่ไหน? ไฟล์ทรัพยากรดิบควรอยู่ที่ไหน สิ่งที่การประชุมคุณควรปฏิบัติตามเพื่อให้แน่ใจว่าการสร้างเครื่องมือในการสร้างR.raw.json_file
?
ตอนนี้ Kotlin เป็นภาษาทางการสำหรับ Android ดังนั้นฉันคิดว่านี่น่าจะเป็นประโยชน์สำหรับใครบางคน
val text = resources.openRawResource(R.raw.your_text_file)
.bufferedReader().use { it.readText() }
ฉันใช้คำตอบของ @ kabuko เพื่อสร้างวัตถุที่โหลดจากไฟล์ JSON โดยใช้Gsonจากทรัพยากร:
package com.jingit.mobile.testsupport;
import java.io.*;
import android.content.res.Resources;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* An object for reading from a JSON resource file and constructing an object from that resource file using Gson.
*/
public class JSONResourceReader {
// === [ Private Data Members ] ============================================
// Our JSON, in string form.
private String jsonString;
private static final String LOGTAG = JSONResourceReader.class.getSimpleName();
// === [ Public API ] ======================================================
/**
* Read from a resources file and create a {@link JSONResourceReader} object that will allow the creation of other
* objects from this resource.
*
* @param resources An application {@link Resources} object.
* @param id The id for the resource to load, typically held in the raw/ folder.
*/
public JSONResourceReader(Resources resources, int id) {
InputStream resourceReader = resources.openRawResource(id);
Writer writer = new StringWriter();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(resourceReader, "UTF-8"));
String line = reader.readLine();
while (line != null) {
writer.write(line);
line = reader.readLine();
}
} catch (Exception e) {
Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
} finally {
try {
resourceReader.close();
} catch (Exception e) {
Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
}
}
jsonString = writer.toString();
}
/**
* Build an object from the specified JSON resource using Gson.
*
* @param type The type of the object to build.
*
* @return An object of type T, with member fields populated using Gson.
*/
public <T> T constructUsingGson(Class<T> type) {
Gson gson = new GsonBuilder().create();
return gson.fromJson(jsonString, type);
}
}
ในการใช้งานคุณจะต้องทำสิ่งต่อไปนี้ (ตัวอย่างอยู่ในInstrumentationTestCase
):
@Override
public void setUp() {
// Load our JSON file.
JSONResourceReader reader = new JSONResourceReader(getInstrumentation().getContext().getResources(), R.raw.jsonfile);
MyJsonObject jsonObj = reader.constructUsingGson(MyJsonObject.class);
}
implementation 'com.google.code.gson:gson:2.8.5'
จากhttp://developer.android.com/guide/topics/resources/providing-resources.html :
ไฟล์ดิบ /ตามอำเภอใจเพื่อบันทึกในรูปแบบดิบ หากต้องการเปิดทรัพยากรเหล่านี้ด้วย InputStream แบบดิบให้เรียก Resources.openRawResource () ด้วยรหัสทรัพยากรซึ่งก็คือ R.raw.filenameอย่างไรก็ตามหากคุณต้องการเข้าถึงชื่อไฟล์ต้นฉบับและลำดับชั้นของไฟล์คุณอาจพิจารณาบันทึกทรัพยากรบางอย่างในเนื้อหา / ไดเร็กทอรี (แทน res / raw /) ไฟล์ในเนื้อหา / ไม่ได้รับ ID ทรัพยากรดังนั้นคุณสามารถอ่านได้โดยใช้ AssetManager เท่านั้น
เช่นเดียวกับสถานะ @mah เอกสาร Android ( https://developer.android.com/guide/topics/resources/providing-resources.html ) บอกว่าไฟล์ json อาจถูกบันทึกในไดเร็กทอรี / raw ภายใต้ / res (ทรัพยากร) ไดเรกทอรีในโครงการของคุณตัวอย่างเช่น:
MyProject/
src/
MyActivity.java
res/
drawable/
graphic.png
layout/
main.xml
info.xml
mipmap/
icon.png
values/
strings.xml
raw/
myjsonfile.json
ภายในActivity
ไฟล์ json สามารถเข้าถึงได้ผ่านR
คลาส (Resources) และอ่านเป็นสตริง:
Context context = this;
Inputstream inputStream = context.getResources().openRawResource(R.raw.myjsonfile);
String jsonString = new Scanner(inputStream).useDelimiter("\\A").next();
สิ่งนี้ใช้คลาส Java Scanner
ทำให้มีบรรทัดของโค้ดน้อยกว่าวิธีอื่น ๆ ในการอ่านไฟล์ text / json แบบธรรมดา รูปแบบตัวคั่น\A
หมายถึง 'จุดเริ่มต้นของอินพุต' .next()
อ่านโทเค็นถัดไปซึ่งเป็นไฟล์ทั้งหมดในกรณีนี้
มีหลายวิธีในการแยกวิเคราะห์สตริง json ที่เป็นผลลัพธ์:
optString(String name)
, optInt(String name)
วิธีการอื่น ๆ ไม่ได้getString(String name)
, getInt(String name)
วิธีการเพราะopt
วิธีการกลับ null แทนที่จะเป็นข้อยกเว้นในกรณีของความล้มเหลวimport java.util.Scanner; import java.io.InputStream; import android.content.Context;
InputStream is = mContext.getResources().openRawResource(R.raw.json_regions);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String json = new String(buffer, "UTF-8");
ใช้:
String json_string = readRawResource(R.raw.json)
ฟังก์ชั่น:
public String readRawResource(@RawRes int res) {
return readStream(context.getResources().openRawResource(res));
}
private String readStream(InputStream is) {
Scanner s = new Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
พบว่าตัวอย่างข้อมูล Kotlin นี้มีประโยชน์มาก ♥️
ในขณะที่คำถามเดิมขอให้รับ JSON String แต่ฉันคิดว่าบางคนอาจพบว่ามีประโยชน์ ก้าวไปอีกขั้นด้วยGson
โอกาสในการขายไปยังฟังก์ชันเล็ก ๆ นี้ด้วยประเภท reified:
private inline fun <reified T> readRawJson(@RawRes rawResId: Int): T {
resources.openRawResource(rawResId).bufferedReader().use {
return gson.fromJson<T>(it, object: TypeToken<T>() {}.type)
}
}
โปรดทราบว่าคุณไม่ต้องการใช้TypeToken
เพียงแค่T::class
นั้นหากคุณอ่านไฟล์List<YourType>
คุณจะไม่สูญเสียประเภทตามประเภทการลบ
ด้วยการอนุมานประเภทคุณสามารถใช้ดังนี้:
fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)