Android czyta tekstowy nieprzetworzony plik zasobów

123

Sprawy są proste, ale nie działają tak, jak powinny.

Mam plik tekstowy dodany jako surowiec. Plik tekstowy zawiera tekst taki jak:

b) JEŚLI OBOWIĄZUJĄCE PRAWO WYMAGA JAKICHKOLWIEK GWARANCJI W ODNIESIENIU DO OPROGRAMOWANIA, WSZYSTKIE TAKIE GWARANCJE SĄ OGRANICZONE DO DZIEWIĘCIĘCIU (90) DNI OD DATY DOSTAWY.

(c) ŻADNE USTNE ANI PISEMNE INFORMACJE ANI PORADY UDZIELANE PRZEZ WIRTUALNĄ ORIENTACJĘ, JEJ DEALERÓW, DYSTRYBUTORÓW, AGENTÓW ANI PRACOWNIKÓW NIE STANOWIĄ GWARANCJI ANI W ŻADNYM SPOSÓB ZWIĘKSZA ZAKRESU JAKIEJKOLWIEK GWARANCJI PRZEDSTAWIONEJ TUTAJ.

(d) (tylko USA) NIEKTÓRE STANY NIE ZEZWALAJĄ NA WYŁĄCZENIE GWARANCJI DOMNIEMANYCH, WIĘC POWYŻSZE WYŁĄCZENIE MOŻE NIE DOTYCZYĆ CIEBIE. NINIEJSZA GWARANCJA DAJE UŻYTKOWNIKOWI OKREŚLONE PRAWA, A UŻYTKOWNIK MOŻE MIEĆ RÓWNIEŻ INNE PRAWA, KTÓRE RÓŻNIĄ SIĘ W ZALEŻNOŚCI OD KRAJU.

Na moim ekranie mam taki układ:

<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>

Kod do odczytu surowego zasobu to:

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();
}

Pojawia się tekst, ale po każdej linii pojawia się dziwny znak [] Jak mogę usunąć ten znak? Myślę, że to New Line.

ROZWIĄZANIE PRACY

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

    InputStreamReader inputreader = new InputStreamReader(inputStream);
    BufferedReader buffreader = new BufferedReader(inputreader);
    String line;
    StringBuilder text = new StringBuilder();

    try {
        while (( line = buffreader.readLine()) != null) {
            text.append(line);
            text.append('\n');
        }
    } catch (IOException e) {
        return null;
    }
    return text.toString();
}
Alin
źródło
3
Wskazówka: możesz dodać adnotację do parametru rawRes za pomocą @RawRes, aby Android Studio spodziewał się surowych zasobów.
Roel
Działające rozwiązanie należy zamieścić jako odpowiedź, gdzie można je przegłosować.
LarsH

Odpowiedzi:

65

Co się stanie, jeśli użyjesz bufora BufferedReader opartego na znakach zamiast bajtowego InputStream?

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

Nie zapominaj, że readLine()pomija nowe linie!

Weekens
źródło
162

Możesz użyć tego:

    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
źródło
5
Nie jestem pewien, czy Inputstream.available () jest tutaj właściwym wyborem, raczej przeczytaj n do ByteArrayOutputStream aż do n == -1.
ThomasRS
15
Może to nie działać w przypadku dużych zasobów. Zależy to od rozmiaru bufora odczytu strumienia wejściowego i może zwrócić tylko część zasobu.
d4n3
6
@ d4n3 ma rację, dokumentacja dostępnej metody strumienia wejściowego mówi: „Zwraca szacunkową liczbę bajtów, które można odczytać lub pominąć bez blokowania dla większej liczby danych wejściowych. Należy zauważyć, że ta metoda zapewnia tak słabą gwarancję, że nie jest zbyt przydatna w praktyka ”
ozba
Spójrz na dokumentację systemu Android dotyczącą InputStream.available. Jeśli dobrze rozumiem, mówią, że nie powinno się go używać do tego celu. Kto by pomyślał, że tak trudno będzie odczytać zawartość głupiego pliku ...
anhoppe
2
I nie powinieneś łapać ogólnego wyjątku. Zamiast tego złap IOException.
alcsan
30

Jeśli używasz IOUtils z Apache „commons-io”, jest to jeszcze łatwiejsze:

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

Zależności: 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
źródło
1
Co należy zaimportować, aby używać IOUtils?
UŻYTKOWNIK
1
Biblioteka Apache commons-io ( commons.apache.org/proper/commons-io ). Lub jeśli używasz Maven ( mvnrepository.com/artifact/commons-io/commons-io ).
tbraun
8
Dla gradle: compile "commons-io: commons-io: 2.1"
JustinMorris
9
Ale generalnie importowanie zewnętrznych bibliotek zewnętrznych w celu uniknięcia pisania 3 kolejnych linii kodu ... wydaje się przesadą.
milosmns
12

Cóż, z Kotlinem możesz to zrobić tylko w jednej linii kodu:

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

Lub nawet zadeklaruj funkcję rozszerzenia:

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

A potem po prostu użyj go od razu:

val txtFile = resources.getRawTextFile(R.raw.rawtextsample)
Arsenius
źródło
Jesteś aniołem.
Robert Liberatore
To była jedyna rzecz, która działała dla mnie! Dziękuję Ci!
fuomag9
Miły! Zrobiłeś mój dzień!
cesards
3

Raczej zrób to w ten sposób:

// 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"));
}

Z działania dodaj

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

lub z przypadku testowego , dodaj

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

I uważaj na obsługę błędów - nie wychwytuj i nie ignoruj ​​wyjątków, gdy zasoby muszą istnieć lub coś jest (bardzo?) Nie tak.

ThomasRS
źródło
Czy musisz zamknąć strumień otwarty przez openRawResource()?
Alex Semeniuk
Nie wiem, ale to z pewnością standard. Aktualizowanie przykładów.
ThomasRS
2

To kolejna metoda, która na pewno zadziała, ale nie mogę jej sprawić, aby czytać wiele plików tekstowych w celu wyświetlenia wielu widoków tekstu w ramach jednej czynności. Każdy może pomóc?

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
źródło
2

@borislemke możesz to zrobić w podobny sposób jak

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
źródło
2

Oto mieszanka rozwiązań Weekens i Vovodroid.

Jest bardziej poprawne niż rozwiązanie Vovodroid i bardziej kompletne niż rozwiązanie Weekensa.

    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
źródło
2

Oto prosta metoda odczytu pliku tekstowego z folderu raw :

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
źródło
2

Oto realizacja w Kotlinie

    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
źródło
1

1. Najpierw utwórz folder Katalog i nazwij go raw w folderze res 2. utwórz plik .txt w folderze katalogu raw, który utworzyłeś wcześniej i nadaj mu dowolną nazwę, np. Articles.txt .... 3. skopiuj i wklej plik. tekst, który chcesz umieścić w utworzonym pliku .txt „artykuły.txt” 4. nie zapomnij dołączyć widoku tekstu do pliku 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();
}

Mam nadzieję, że zadziałało!

Frankrnz
źródło
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());
sakshi agrawal
źródło