Saugat Rai
Saugat Rai

Reputation: 125

How to read json file from assests in android using Kotlin?

I have already done with java but find difficult with Kotlin.

I have already search with google but none of them work for me.

/**
 * Get the json data from json file.
 *
 * @param context  the context to acces the resources.
 * @param fileName the name of the json file
 * @return json as string
 */
public static String getJsonFromAsset(Context context, String fileName) {
    String json = "";
    try {
        InputStream stream = context.getAssets().open(fileName);
        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        json = new String(buffer, "UTF-8");

    } catch (Exception e) {
        e.printStackTrace();
    }
    return json;
}

I want this code in Kotlin.

Upvotes: 6

Views: 21126

Answers (6)

Lawrence Gimenez
Lawrence Gimenez

Reputation: 3255

Same with the top answer but, if you are using Jetpack Compose

@Composable
fun HomeScreen() {
    val fileInString = LocalContext.current.assets.open("test.json").bufferedReader().use {
        it.readText()
    }
}

Upvotes: 0

Behzod Halil
Behzod Halil

Reputation: 21

To guarantee testability and maintainability, I would suggest to make interface with readJsonFile function:

interface JsonAssets {
  suspend fun readJsonFile(fileName: String): Result<Data>
}

In the implementation details, to perform file reading in a thread-safety, I used Coroutine with withContext(Dispatchers.IO). This provides the block of code runs on the background thread.

class DefaultJsonAssets : JsonAssets {

override suspend fun readJsonFile(fileName: String): Result<Data> = withContext(Dispatchers.IO) {
    try {
      val classLoader = javaClass.classLoader
      val inputStream: InputStream? = classLoader?.getResourceAsStream(fileName)

      if (inputStream != null) {
        val jsonString = inputStream.bufferedReader().use { it.readText() }
        val data = Json.decodeFromString(SomeDataSerializer, jsonString)
        Result.success(data)
      } else {
        Result.failure(Exception("File not found: $fileName"))
      }
    } catch (e: Exception) {
      Result.failure(e)
    }
  }

If the file is found, it reads the content, deserializes it into a SomeData using a Json decoder, and returns a Result.success. If the file is not found, it returns a Result.failure with an appropriate exception.

Upvotes: 2

Muhammad Amjad
Muhammad Amjad

Reputation: 1

fun loadAssetsFromFile ( context : Context ) {

    val inputStream = context.assets.open("example.json")
    val size = inputStream.available()
    val buffer = ByteArray(size)
    inputStream.read(buffer)
    inputStream.close()
    val json = String(buffer, charset = UTF_8)
    val gson = Gson()
    data = gson.fromJson(json, Array<Quote>::class.java)
}

Upvotes: 0

Amit Gupta
Amit Gupta

Reputation: 663

You can use the following

class LocalJSONParser {

companion object {
    fun inputStreamToString(inputStream: InputStream): String {
        try {
            val bytes = ByteArray(inputStream.available())
            inputStream.read(bytes, 0, bytes.size)
            return String(bytes)
        } catch (e: IOException) {
            return ""
        }
      }
    }
}

// jsonFileName = "data.json"
inline fun <reified T> Context.getObjectFromJson(jsonFileName: String): T {
val myJson =LocalJSONParser.inputStreamToString(this.assets.open(jsonFileName))
return Gson().fromJson(myJson, T::class.java
}

Upvotes: 1

AbuMaaiz
AbuMaaiz

Reputation: 572

Reading json file from assets folder in Kotlin is very easy, just use the following code

val fileInString: String =
  applicationContext.assets.open(fileName).bufferedReader().use { it.readText() }

Upvotes: 20

Sagar Chapagain
Sagar Chapagain

Reputation: 1763

Java codes can be converted to Kotlin from Android Studio too. Here is the converted solution with the extension function of Context.

@Throws(IOException::class)
fun Context.readJsonAsset(fileName: String): String {
    val inputStream = assets.open(fileName)
    val size = inputStream.available()
    val buffer = ByteArray(size)
    inputStream.read(buffer)
    inputStream.close()
    return String(buffer, Charsets.UTF_8)
}

Upvotes: 4

Related Questions