Giả sử tôi có một tệp có nội dung JSON trong thư mục tài nguyên thô trong ứng dụng của mình. Làm cách nào để tôi có thể đọc nội dung này vào ứng dụng để có thể phân tích cú pháp JSON?
Câu trả lời:
Xem openRawResource . Một cái gì đó như thế này sẽ hoạt động:
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
thư mục hoặc bên trong \res\raw\json_file.json
?
getResources()
thể gọi là ở đâu? Tệp tài nguyên thô nên đi đâu? Bạn nên tuân theo quy ước nào để đảm bảo các công cụ xây dựng được tạo ra R.raw.json_file
?
Kotlin hiện là ngôn ngữ chính thức cho Android, vì vậy tôi nghĩ điều này sẽ hữu ích cho ai đó
val text = resources.openRawResource(R.raw.your_text_file)
.bufferedReader().use { it.readText() }
Tôi đã sử dụng câu trả lời của @ kabuko để tạo một đối tượng tải từ tệp JSON, sử dụng Gson , từ Tài nguyên:
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);
}
}
Để sử dụng nó, bạn sẽ làm như sau (ví dụ trong một 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'
Từ http://developer.android.com/guide/topics/resources/providing-resources.html :
tệp thô / Tùy ý để lưu ở dạng thô. Để mở các tài nguyên này bằng InputStream thô, hãy gọi Resources.openRawResource () với ID tài nguyên là R.raw.filename.Tuy nhiên, nếu bạn cần quyền truy cập vào tên tệp gốc và phân cấp tệp, bạn có thể cân nhắc lưu một số tài nguyên trong thư mục nội dung / (thay vì res / raw /). Các tệp trong nội dung / không được cung cấp ID tài nguyên, vì vậy bạn chỉ có thể đọc chúng bằng AssetManager.
Giống như trạng thái @mah, tài liệu Android ( https://developer.android.com/guide/topics/resources/providing-resources.html ) cho biết tệp json có thể được lưu trong thư mục / raw trong / res (tài nguyên) thư mục trong dự án của bạn, ví dụ:
MyProject/
src/
MyActivity.java
res/
drawable/
graphic.png
layout/
main.xml
info.xml
mipmap/
icon.png
values/
strings.xml
raw/
myjsonfile.json
Bên trong một Activity
, tệp json có thể được truy cập thông qua lớp R
(Tài nguyên) và đọc đến một Chuỗi:
Context context = this;
Inputstream inputStream = context.getResources().openRawResource(R.raw.myjsonfile);
String jsonString = new Scanner(inputStream).useDelimiter("\\A").next();
Điều này sử dụng lớp Java Scanner
, dẫn đến ít dòng mã hơn so với một số phương pháp đọc tệp văn bản / json đơn giản khác. Mẫu dấu phân cách \A
có nghĩa là 'đầu của đầu vào'. .next()
đọc mã thông báo tiếp theo, là toàn bộ tệp trong trường hợp này.
Có nhiều cách để phân tích cú pháp chuỗi json kết quả:
optString(String name)
, optInt(String name)
vv phương pháp, không phải là getString(String name)
, getInt(String name)
phương pháp, bởi vìopt
phương pháp trả về null thay vì một ngoại lệ trong trường hợp thất bại.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");
Sử dụng:
String json_string = readRawResource(R.raw.json)
Chức năng:
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() : "";
}
Tìm thấy câu trả lời đoạn trích Kotlin này rất hữu ích ♥ ️
Trong khi câu hỏi ban đầu yêu cầu lấy Chuỗi JSON, tôi nghĩ một số có thể thấy điều này hữu ích. Một bước xa hơn với Gson
dẫn đến chức năng nhỏ này với loại được sửa đổi:
private inline fun <reified T> readRawJson(@RawRes rawResId: Int): T {
resources.openRawResource(rawResId).bufferedReader().use {
return gson.fromJson<T>(it, object: TypeToken<T>() {}.type)
}
}
Lưu ý rằng bạn không muốn sử dụng TypeToken
chỉ T::class
như vậy nếu bạn đọcList<YourType>
bạn sẽ không bị mất loại theo loại tẩy xóa.
Với kiểu suy luận bạn có thể sử dụng như sau:
fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)