68

I need to load an xml file as String in android so I can load it to TBXML xml parser library and parse it. The implementation I have now to read the file as String takes around 2seconds even for a very small xml file of some KBs. Is there any known fast method that can read a file as string in Java/Android?


This is the code I have now:

public static String readFileAsString(String filePath) { String result = ""; File file = new File(filePath); if ( file.exists() ) { //byte[] buffer = new byte[(int) new File(filePath).length()]; FileInputStream fis = null; try { //f = new BufferedInputStream(new FileInputStream(filePath)); //f.read(buffer); fis = new FileInputStream(file); char current; while (fis.available() > 0) { current = (char) fis.read(); result = result + String.valueOf(current); } } catch (Exception e) { Log.d("TourGuide", e.toString()); } finally { if (fis != null) try { fis.close(); } catch (IOException ignored) { } } //result = new String(buffer); } return result; } 
5
  • check this stackoverflow.com/questions/326390/… Commented Oct 16, 2012 at 8:32
  • depends on how you currently read the file. post your code so someone can help you. Commented Oct 16, 2012 at 8:32
  • I don't have the code with me now. I will post it later. But any suggestions are welcome until then :) Commented Oct 16, 2012 at 8:47
  • 1
    Panos, i don't know how you parse your XML file, but try adding at a StringBuffer object each line, instead of adding to a String. StringBuffer is faster. Commented Oct 16, 2012 at 8:55
  • please check the code I'm using and advice. I see I have the string concatenation there. I will change that. Any other advice? Commented Oct 16, 2012 at 21:49

7 Answers 7

165

The code finally used is the following from:

http://www.java2s.com/Code/Java/File-Input-Output/ConvertInputStreamtoString.htm public static String convertStreamToString(InputStream is) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } reader.close(); return sb.toString(); } public static String getStringFromFile (String filePath) throws Exception { File fl = new File(filePath); FileInputStream fin = new FileInputStream(fl); String ret = convertStreamToString(fin); //Make sure you close all streams. fin.close(); return ret; } 
Sign up to request clarification or add additional context in comments.

5 Comments

Doesn't seem right to me that your first fn closes a stream that it didn't open. In other words, I think getStringFromFile should close the stream.
@Tom Actually the important part in this answer is to show what happens in the loop and creates the string. Anyway , you were right that it is nicer to close the stream in getStringFromFile, so I edited the answer. Thanks.
Won't this add an extra new line at the end of the string?
@JaredRummler Yes it will. Plus it will modify the line endings of your file to '\n' always, which may very well not be what you want. Again, doing something in java is harder than it needs to be.
It's safer to use Uri in Android. File path may or may not work.
17

You can use org.apache.commons.io.IOUtils.toString(InputStream is, Charset chs) to do that.

e.g.

IOUtils.toString(context.getResources().openRawResource(<your_resource_id>), StandardCharsets.UTF_8) 

For adding the correct library:

Add the following to your app/build.gradle file:

dependencies { compile 'org.apache.directory.studio:org.apache.commons.io:2.4' } 

or for the Maven repo see -> this link

For direct jar download see-> https://commons.apache.org/proper/commons-io/download_io.cgi

7 Comments

Method is Deprecated, just added Charset-> public static String toString(InputStream input, Charset encoding) see -> commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#toString(java.io.InputStream, java.nio.charset.Charset)
Maybe now it is, at the time of writing this answer it wasn't. I can update the answer with info from your comment if you don't mind. Or you can write your own answer :)
I don't mind, and it would not matter if I did, IMHO, you should update the answer to keep it relevant regardless, as I would.
I did write my own answer stackoverflow.com/a/36701219/181562 which contained source was used for obtaining an asset...though for the given question, I do believe that the brevity of your answer renders it the best...
Can you please clarify what is 'resource ID' - I create a directory called /assets under /main and have a sampleText.txt file there. How do I call that file as input? Please help.
|
16

Reworked the method set originating from -> the accepted answer

@JaredRummler An answer to your comment:

Read file As String

Won't this add an extra new line at the end of the string?

To prevent having a newline added at the end you can use a Boolean value set during the first loop as you will in the code example Boolean firstLine

public static String convertStreamToString(InputStream is) throws IOException { // http://www.java2s.com/Code/Java/File-Input-Output/ConvertInputStreamtoString.htm BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; Boolean firstLine = true; while ((line = reader.readLine()) != null) { if(firstLine){ sb.append(line); firstLine = false; } else { sb.append("\n").append(line); } } reader.close(); return sb.toString(); } public static String getStringFromFile (String filePath) throws IOException { File fl = new File(filePath); FileInputStream fin = new FileInputStream(fl); String ret = convertStreamToString(fin); //Make sure you close all streams. fin.close(); return ret; } 

1 Comment

This still modifies the line endings to '\n'. There doesn't seem to be an easy way around that.
11

It's very easy if you use Kotlin:

val textFile = File(cacheDir, "/text_file.txt") val allText = textFile.readText() println(allText) 

From readText() docs:

Gets the entire content of this file as a String using UTF-8 or specified charset. This method is not recommended on huge files. It has an internal limitation of 2 GB file size.

6 Comments

he's not using Kotlin. Question is for Java.
@StealthRabbi In the question the op is asking how to do it in Java/Android. At the time Java was the primary language for Android, so it makes sense to post the Kotlin version now. Also the question tags only include Android which I assume is what's more important.
Right, and he didn't use the Java tag because it was assumed, given the age of the question. It's like if I asked how to travel fast between cities in 1870, and you respond 100 years later telling me to take an airplane.
@StealthRabbi For a person reading the above mentioned hypothetical question after 100 years, taking an airplane is the accepted right answer.
I wrote the original question in the 1800s. We got some nice solutions back in the day. But this is also a very good acceptable solution so we can see the evolution of the JVM apis and solutions
|
6

With files we know the size in advance, so just read it all at once!

String result; File file = ...; long length = file.length(); if (length < 1 || length > Integer.MAX_VALUE) { result = ""; Log.w(TAG, "File is empty or huge: " + file); } else { try (FileReader in = new FileReader(file)) { char[] content = new char[(int)length]; int numRead = in.read(content); if (numRead != length) { Log.e(TAG, "Incomplete read of " + file + ". Read chars " + numRead + " of " + length); } result = new String(content, 0, numRead); } catch (Exception ex) { Log.e(TAG, "Failure reading " + this.file, ex); result = ""; } } 

3 Comments

No idea why this got downvoted. Sure, the code is cluttered, but this will work (and if he runs out of memory allocating a buffer for a large file, so would the examples that use a StringBuffer). It also won't add an extra new-line, which the top-voted answer does.
the comparison at the end of numRead and length compares chars to bytes. It can happen that those are not equal, when the whole file was read.
FileReader in = new FileReader(file) requires api level 19
-2
public static String readFileToString(String filePath) { InputStream in = Test.class.getResourceAsStream(filePath);//filePath="/com/myproject/Sample.xml" try { return IOUtils.toString(in, StandardCharsets.UTF_8); } catch (IOException e) { logger.error("Failed to read the xml : ", e); } return null; } 

Comments

-15

this is working for me

i use this path String FILENAME_PATH = "/mnt/sdcard/Download/Version"; public static String getStringFromFile (String filePath) throws Exception { File fl = new File(filePath); FileInputStream fin = new FileInputStream(fl); String ret = convertStreamToString(fin); //Make sure you close all streams. fin.close(); return ret; } 

2 Comments

What is convertStreamToString?
sad half-copy-past

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.