138

I have a text file added as a raw resource. The text file contains text like:

b) IF APPLICABLE LAW REQUIRES ANY WARRANTIES WITH RESPECT TO THE
SOFTWARE, ALL SUCH WARRANTIES ARE 
LIMITED IN DURATION TO NINETY (90)
DAYS FROM THE DATE OF  DELIVERY.

(c) NO ORAL OR WRITTEN INFORMATION OR
ADVICE GIVEN BY  VIRTUAL ORIENTEERING,
ITS DEALERS, DISTRIBUTORS, AGENTS OR
EMPLOYEES SHALL CREATE A WARRANTY OR
IN ANY WAY INCREASE THE SCOPE OF ANY
WARRANTY PROVIDED HEREIN. 

(d) (USA only) SOME STATES DO NOT
ALLOW THE EXCLUSION OF IMPLIED
WARRANTIES, SO THE ABOVE EXCLUSION MAY
NOT  APPLY TO YOU. THIS WARRANTY GIVES
YOU SPECIFIC LEGAL  RIGHTS AND YOU MAY
ALSO HAVE OTHER LEGAL RIGHTS THAT 
VARY FROM STATE TO STATE.

On my screen I have a layout like this:

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
                     android:layout_width="fill_parent" 
                     android:layout_height="wrap_content" 
                     android:gravity="center" 
                     android:layout_weight="1.0"
                     android:layout_below="@+id/logoLayout"
                     android:background="@drawable/list_background"> 
            
            <ScrollView android:layout_width="fill_parent"
                        android:layout_height="fill_parent">
                        
                    <TextView  android:id="@+id/txtRawResource" 
                               android:layout_width="fill_parent" 
                               android:layout_height="fill_parent"
                               android:padding="3dip"/>
            </ScrollView>  
   
    </LinearLayout>

The code to read the raw resource is:

TextView txtRawResource= (TextView)findViewById(R.id.txtRawResource);

txtDisclaimer.setText(Utils.readRawTextFile(ctx, R.raw.rawtextsample);

public static String readRawTextFile(Context ctx, int resId)
{
    InputStream inputStream = ctx.getResources().openRawResource(resId);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    int i;
    try {
        i = inputStream.read();
        while (i != -1)
        {
            byteArrayOutputStream.write(i);
            i = inputStream.read();
        }
        inputStream.close();
    } catch (IOException e) {
        return null;
    }
    return byteArrayOutputStream.toString();
}

The text is shown but after each line I get the strange characters []. How can I remove the characters? I think it's a newline.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Alin
  • 14,809
  • 40
  • 129
  • 218
  • 3
    Hint: You can annotate your rawRes Parameter with @RawRes so Android Studio exspects raw resources. – Roel Sep 12 '18 at 12:10
  • 1
    The working solution should be posted as an Answer, where it can be upvoted. – LarsH May 21 '19 at 14:58

14 Answers14

173

You can use this:

    try {
        Resources res = getResources();
        InputStream in_s = res.openRawResource(R.raw.help);

        byte[] b = new byte[in_s.available()];
        in_s.read(b);
        txtHelp.setText(new String(b));
    } catch (Exception e) {
        // e.printStackTrace();
        txtHelp.setText("Error: can't show help.");
    }
Vovodroid
  • 1,787
  • 2
  • 10
  • 2
  • 5
    I am not sure the Inputstream.available() is the correct choice here, rather read n to a ByteArrayOutputStream untill n == -1. – ThomasRS Apr 30 '12 at 08:32
  • 15
    This may not work for large resources. It depends on the size of the inputstream read buffer and could only return a part of the resource. – d4n3 Jun 29 '12 at 06:19
  • 6
    @d4n3 is right, the documentation of the input stream available method states: "Returns an estimated number of bytes that can be read or skipped without blocking for more input. Note that this method provides such a weak guarantee that it is not very useful in practice" – ozba Apr 10 '13 at 14:18
  • 1
    Look at the android docs for InputStream.available. If I get it right they say that it should not be used for this purpose. Who'd thought that it be that hard to read the content of a stupid file... – anhoppe Dec 19 '14 at 21:09
  • 3
    And you should not catch general Exception. Catch IOException instead. – alcsan Jul 19 '16 at 22:08
77

What if you use a character-based BufferedReader instead of byte-based InputStream?

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();
while (line != null) { 
    ...
    line = reader.readLine();
}

Don't forget that readLine() skips the new-lines!

Jaspal
  • 601
  • 2
  • 13
  • 23
weekens
  • 8,064
  • 6
  • 45
  • 62
  • For me worked this: InputStream is = my_app_context.getResources().openRawResource(R.raw.name_of_text_file); Scanner text_scanner = new Scanner(is); //Have fun! – TomeeNS Apr 16 '22 at 18:57
54

Well with Kotlin u can do it just in one line of code:

resources.openRawResource(R.raw.rawtextsample).bufferedReader().use { it.readText() }

Or even declare extension function:

fun Resources.getRawTextFile(@RawRes id: Int) =
        openRawResource(id).bufferedReader().use { it.readText() }

And then just use it straightaway:

val txtFile = resources.getRawTextFile(R.raw.rawtextsample)
Arsenius
  • 4,972
  • 4
  • 26
  • 39
  • 2
    You're an angel. – Bob Liberatore Jan 18 '20 at 04:12
  • This was the only thing that worked for me! Thank you! – fuomag9 Feb 09 '20 at 12:18
  • Is there a need to specify a `charset`? I don't see that `readText` takes such parameters, is this safe? Or it's better to convert from a `ByteArray` using a specific `charset`? – Tamim Attafi Apr 26 '23 at 05:07
  • 1
    @TamimAttafi default charset for `readText` is `UTF-8` if your text in different charset u have to set it explicitly. Yes is safe as long as text not not too large and charset of source text is `UTF-8`. – Arsenius Apr 26 '23 at 07:57
32

If you use IOUtils from apache "commons-io" it's even easier:

InputStream is = getResources().openRawResource(R.raw.yourNewTextFile);
String s = IOUtils.toString(is);
IOUtils.closeQuietly(is); // don't forget to close your streams

Dependencies: http://mvnrepository.com/artifact/commons-io/commons-io

Maven:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

Gradle:

'commons-io:commons-io:2.4'
tbraun
  • 2,636
  • 31
  • 26
4

Rather do it this way:

// reads resources regardless of their size
public byte[] getResource(int id, Context context) throws IOException {
    Resources resources = context.getResources();
    InputStream is = resources.openRawResource(id);

    ByteArrayOutputStream bout = new ByteArrayOutputStream();

    byte[] readBuffer = new byte[4 * 1024];

    try {
        int read;
        do {
            read = is.read(readBuffer, 0, readBuffer.length);
            if(read == -1) {
                break;
            }
            bout.write(readBuffer, 0, read);
        } while(true);

        return bout.toByteArray();
    } finally {
        is.close();
    }
}

    // reads a string resource
public String getStringResource(int id, Charset encoding) throws IOException {
    return new String(getResource(id, getContext()), encoding);
}

    // reads an UTF-8 string resource
public String getStringResource(int id) throws IOException {
    return new String(getResource(id, getContext()), Charset.forName("UTF-8"));
}

From an Activity, add

public byte[] getResource(int id) throws IOException {
        return getResource(id, this);
}

or from a test case, add

public byte[] getResource(int id) throws IOException {
        return getResource(id, getContext());
}

And watch your error handling - don't catch and ignore exceptions when your resources must exist or something is (very?) wrong.

Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
ThomasRS
  • 8,215
  • 5
  • 33
  • 48
3

@borislemke you can do this by similar way like

TextView  tv ;
findViewById(R.id.idOfTextView);
tv.setText(readNewTxt());
private String readNewTxt(){
InputStream inputStream = getResources().openRawResource(R.raw.yourNewTextFile);
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

 int i;
 try {
 i = inputStream.read();
while (i != -1)
  {
   byteArrayOutputStream.write(i);
   i = inputStream.read();
   }
    inputStream.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
 e.printStackTrace();
 }

 return byteArrayOutputStream.toString();
 }
Manish Sharma
  • 217
  • 1
  • 2
  • 11
2

Here goes mix of weekens's and Vovodroid's solutions.

It is more correct than Vovodroid's solution and more complete than weekens's solution.

    try {
        InputStream inputStream = res.openRawResource(resId);
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                StringBuilder result = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    result.append(line);
                }
                return result.toString();
            } finally {
                reader.close();
            }
        } finally {
            inputStream.close();
        }
    } catch (IOException e) {
        // process exception
    }
alcsan
  • 6,172
  • 1
  • 23
  • 19
2

Here is a simple method to read the text file from the raw folder:

public static String readTextFile(Context context,@RawRes int id){
    InputStream inputStream = context.getResources().openRawResource(id);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte buffer[] = new byte[1024];
    int size;
    try {
        while ((size = inputStream.read(buffer)) != -1) 
            outputStream.write(buffer, 0, size);
        outputStream.close();
        inputStream.close();
    } catch (IOException e) {

    }
    return outputStream.toString();
}
ucMedia
  • 4,105
  • 4
  • 38
  • 46
2

Here is an implementation in Kotlin

    try {
        val inputStream: InputStream = this.getResources().openRawResource(R.raw.**)
        val inputStreamReader = InputStreamReader(inputStream)
        val sb = StringBuilder()
        var line: String?
        val br = BufferedReader(inputStreamReader)
        line = br.readLine()
        while (line != null) {
            sb.append(line)
            line = br.readLine()
        }
        br.close()

        var content : String = sb.toString()
        Log.d(TAG, content)
    } catch (e:Exception){
        Log.d(TAG, e.toString())
    }
semloh eh
  • 29
  • 2
2

This is another method which will definitely work, but I cant get it to read multiple text files to view in multiple textviews in a single activity, anyone can help?

TextView helloTxt = (TextView)findViewById(R.id.yourTextView);
    helloTxt.setText(readTxt());
}

private String readTxt(){

 InputStream inputStream = getResources().openRawResource(R.raw.yourTextFile);
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

 int i;
try {
i = inputStream.read();
while (i != -1)
  {
   byteArrayOutputStream.write(i);
   i = inputStream.read();
  }
  inputStream.close();
} catch (IOException e) {
 // TODO Auto-generated catch block
e.printStackTrace();
}

 return byteArrayOutputStream.toString();
}
borislemke
  • 8,446
  • 5
  • 41
  • 54
1

1.First create a Directory folder and name it raw inside the res folder 2.create a .txt file inside the raw directory folder you created earlier and give it any name eg.articles.txt.... 3.copy and paste the text you want inside the .txt file you created"articles.txt" 4.dont forget to include a textview in your main.xml MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gettingtoknowthe_os);

    TextView helloTxt = (TextView)findViewById(R.id.gettingtoknowos);
    helloTxt.setText(readTxt());

    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();//to exclude the ActionBar
}

private String readTxt() {

    //getting the .txt file
    InputStream inputStream = getResources().openRawResource(R.raw.articles);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    try {
        int i = inputStream.read();
        while (i != -1) {
            byteArrayOutputStream.write(i);
            i = inputStream.read();
        }
        inputStream.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
    return byteArrayOutputStream.toString();
}

Hope it worked!

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Frankrnz
  • 694
  • 6
  • 5
1
InputStream is=getResources().openRawResource(R.raw.name);
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
StringBuffer data=new StringBuffer();
String line=reader.readLine();
while(line!=null)
{
data.append(line+"\n");
}
tvDetails.seTtext(data.toString());
0

Here's a one liner for you:

String text = new BufferedReader(
  new InputStreamReader(getResources().openRawResource(R.raw.my_file)))
  .lines().reduce("\n", (a,b) -> a+b);
Guss
  • 30,470
  • 17
  • 104
  • 128
0
val inputStream: InputStream = resources.openRawResource(R.raw.product_json)
val reader: Reader = BufferedReader(InputStreamReader(inputStream, "utf-8"))

val writer: Writer = StringWriter()
val buffer = CharArray(1024)
reader.use { it ->
    var n: Int
    while (it.read(buffer).also { n = it } != -1) {
        writer.write(buffer, 0, n)
    }
}
val stringVal = writer.toString()
Uddhav P. Gautam
  • 7,362
  • 3
  • 47
  • 64