Read Assets file as string
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.
Solution 1:
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:
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:
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:
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.