Read Assets file as string

AndroidString

Android Problem Overview


I would like to read the content of a file located in the Assets as a String. For example, a text document located in src/main/assets/

Original Question
I found that this question is mostly used as a 'FAQ' for reading an assets file, therefore I summarized the question above. Below is my original question

I'm trying to read a assets file as string. I have a file in my assets folder: data.opml, and want to read it as a string.

Some things I tried:

 AssetFileDescriptor descriptor = getAssets().openFd("data.opml");
 FileReader reader = new FileReader(descriptor.getFileDescriptor());

And also:

 InputStream input = getAssets().open("data.opml");
 Reader reader = new InputStreamReader(input, "UTF-8");

But without success, so a full example would be appreciated.

Android Solutions


Solution 1 - Android

getAssets().open() will return an InputStream. Read from that using standard Java I/O:

Java:

StringBuilder sb = new StringBuilder();
InputStream is = getAssets().open("book/contents.json");
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8 ));
String str;
while ((str = br.readLine()) != null) {
    sb.append(str);
}
br.close();

Kotlin:

val str = assets.open("book/contents.json").bufferedReader().use { it.readText() }

Solution 2 - Android

There is a little bug CommonsWare's code - newline characters are discarded and not added to the string. Here is some fixed code ready for copy+paste:

private String loadAssetTextAsString(Context context, String name) {
		BufferedReader in = null;
		try {
			StringBuilder buf = new StringBuilder();
			InputStream is = context.getAssets().open(name);
			in = new BufferedReader(new InputStreamReader(is));
			
		    String str;
		    boolean isFirst = true;
		    while ( (str = in.readLine()) != null ) {
		    	if (isFirst)
		    		isFirst = false;
		    	else
		    		buf.append('\n');
		    	buf.append(str);
		    }
		    return buf.toString();
		} catch (IOException e) {
			Log.e(TAG, "Error opening asset " + name);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					Log.e(TAG, "Error closing asset " + name);
				}
			}
		}
		
		return null;
	}
	

Solution 3 - Android

You can also do it, without using loops. It's pretty simple

AssetManager assetManager = getAssets();
InputStream input;
String text = "";

	try {
		input = assetManager.open("test.txt");

		int size = input.available();
		byte[] buffer = new byte[size];
		input.read(buffer);
		input.close();

		// byte buffer into a string
		text = new String(buffer);

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

	Log.v("TAG", "Text File: " + text);

Solution 4 - Android

hi this is in my opinion the cleanest approach:

  public static String loadTextFromAssets(Context context, String assetsPath, Charset charset) throws IOException {
        InputStream is = context.getResources().getAssets().open(assetsPath);
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int length = is.read(buffer); length != -1; length = is.read(buffer)) {
            baos.write(buffer, 0, length);
        }
        is.close();
        baos.close();
        return charset == null ? new String(baos.toByteArray()) : new String(baos.toByteArray(), charset);
    }

because readers could get trouble with line breaks.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMdlcView Question on Stackoverflow
Solution 1 - AndroidCommonsWareView Answer on Stackoverflow
Solution 2 - AndroidMichael LitvinView Answer on Stackoverflow
Solution 3 - Androiduser2471325View Answer on Stackoverflow
Solution 4 - AndroidDaniel CraigView Answer on Stackoverflow