Android liest Text Rohressourcendatei


123

Die Dinge sind einfach, funktionieren aber nicht wie vorgesehen.

Ich habe eine Textdatei als Rohstoff hinzugefügt. Die Textdatei enthält Text wie:

b) WENN ANWENDBARES RECHT GEWÄHRLEISTUNGEN IN BEZUG AUF DIE SOFTWARE ERFORDERT, SIND ALLE DIESEN GEWÄHRLEISTUNGEN AUF NEUNZEHN (90) TAGE AB LIEFERDATUM BESCHRÄNKT.

(c) KEINE MÜNDLICHEN ODER SCHRIFTLICHEN INFORMATIONEN ODER RATSCHLÄGE, DIE VON VIRTUAL ORIENTEERING, SEINEN HÄNDLERN, VERTRIEBSPARTNERN, VERTRETERN ODER MITARBEITERN GEGEBEN WERDEN, ERSTELLEN EINE GARANTIE ODER ERHÖHEN IN KEINER WEISE DEN GELTUNGSBEREICH.

(d) (nur USA) EINIGE STAATEN ERLAUBEN DEN AUSSCHLUSS STILLSCHWEIGENDER GEWÄHRLEISTUNGEN NICHT, sodass der oben genannte Ausschluss möglicherweise nicht für Sie gilt. DIESE GARANTIE GIBT IHNEN SPEZIFISCHE RECHTE UND SIE KÖNNEN AUCH ANDERE RECHTE HABEN, DIE VON STAAT ZU STAAT UNTERSCHIEDLICH SIND.

Auf meinem Bildschirm habe ich ein Layout wie folgt:

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

Der Code zum Lesen der Rohressource lautet:

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

Der Text wird angezeigt, aber nach jeder Zeile wird ein seltsames Zeichen angezeigt. [] Wie kann ich dieses Zeichen entfernen? Ich denke es ist New Line.

ARBEITSLÖSUNG

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

3
Tipp: Sie können Ihren rawRes-Parameter mit @RawRes mit Anmerkungen versehen, damit Android Studio die Rohressourcen überprüft.
Roel

Die funktionierende Lösung sollte als Antwort veröffentlicht werden, wo sie bewertet werden kann.
LarsH

Antworten:


65

Was ist, wenn Sie einen zeichenbasierten BufferedReader anstelle eines bytebasierten InputStream verwenden?

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

Vergessen Sie nicht, dass readLine()die neuen Zeilen übersprungen werden!


162

Sie können dies verwenden:

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

5
Ich bin nicht sicher, ob Inputstream.available () hier die richtige Wahl ist, sondern lese n in einen ByteArrayOutputStream, bis n == -1.
ThomasRS

15
Dies funktioniert möglicherweise nicht für große Ressourcen. Dies hängt von der Größe des Eingabestream-Lesepuffers ab und kann nur einen Teil der Ressource zurückgeben.
d4n3

6
@ d4n3 ist richtig, in der Dokumentation der verfügbaren Methode für den Eingabestream heißt es: "Gibt eine geschätzte Anzahl von Bytes zurück, die gelesen oder übersprungen werden können, ohne für weitere Eingaben zu blockieren. Beachten Sie, dass diese Methode eine so schwache Garantie bietet, dass sie in nicht sehr nützlich ist üben "
Ozba

Schauen Sie sich die Android-Dokumente für InputStream.available an. Wenn ich es richtig verstehe, sagen sie, dass es nicht für diesen Zweck verwendet werden sollte. Wer hätte gedacht, dass es so schwer ist, den Inhalt einer dummen Datei zu lesen ...
anhoppe

2
Und Sie sollten keine allgemeine Ausnahme fangen. Catch stattdessen IOException.
Alcsan

30

Wenn Sie IOUtils von Apache "commons-io" verwenden, ist es noch einfacher:

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

Abhängigkeiten: 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'

1
Was muss ich importieren, um IOUtils zu verwenden?
USA

1
Apache commons-io Bibliothek ( commons.apache.org/proper/commons-io ). Oder wenn Sie Maven verwenden ( mvnrepository.com/artifact/commons-io/commons-io ).
Tbraun

8
Für gradle: kompiliere "commons-io: commons-io: 2.1"
JustinMorris

9
Im Allgemeinen scheint das Importieren externer Bibliotheken von Drittanbietern, um das Schreiben von drei weiteren Codezeilen zu vermeiden, ein Overkill zu sein.
Milosmns

12

Nun, mit Kotlin können Sie es nur in einer Codezeile tun:

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

Oder deklarieren Sie sogar die Erweiterungsfunktion:

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

Und dann benutze es einfach sofort:

val txtFile = resources.getRawTextFile(R.raw.rawtextsample)

Du bist ein Engel.
Robert Liberatore

Dies war das einzige, was für mich funktioniert hat! Danke dir!
fuomag9

Nett! Du hast meinen Tag gerettet!
cesards

3

Mach es lieber so:

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

Fügen Sie aus einer Aktivität hinzu

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

oder aus einem Testfall hinzufügen

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

Und beobachten Sie Ihre Fehlerbehandlung - fangen Sie keine Ausnahmen ab und ignorieren Sie sie nicht, wenn Ihre Ressourcen vorhanden sein müssen oder etwas (sehr?) Nicht stimmt.


Müssen Sie den von geöffneten Stream schließen openRawResource()?
Alex Semeniuk

Ich weiß es nicht, aber das ist sicherlich Standard. Beispiele aktualisieren.
ThomasRS

2

Dies ist eine andere Methode, die definitiv funktionieren wird, aber ich kann sie nicht dazu bringen, mehrere Textdateien zu lesen, um sie in mehreren Textansichten in einer einzigen Aktivität anzuzeigen. Kann jemand helfen?

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

2

@borislemke Sie können dies auf ähnliche Weise tun wie

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

2

Hier finden Sie eine Mischung aus Weekens- und Vovodroid-Lösungen.

Es ist korrekter als die Lösung von Vovodroid und vollständiger als die Lösung von Weekens.

    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
    }

2

Hier ist eine einfache Methode , um die lesen Textdatei aus dem rohen Ordner:

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

2

Hier ist eine Implementierung 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())
    }

1

1.Erstellen Sie zuerst einen Verzeichnisordner und benennen Sie ihn roh im Ordner res. 2.Erstellen Sie eine TXT-Datei in dem zuvor erstellten unformatierten Verzeichnisordner und geben Sie ihm einen beliebigen Namen, z. B. Artikel.txt .... 3. Kopieren Sie den Ordner und fügen Sie ihn ein Text, den Sie in der von Ihnen erstellten TXT-Datei "articles.txt" haben möchten 4. Vergessen Sie nicht, eine Textansicht in Ihre main.xml MainActivity.java aufzunehmen

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

Hoffe es hat funktioniert!


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());
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.