Android legge il file di risorse raw di testo


123

Le cose sono semplici ma non funzionano come dovrebbero.

Ho un file di testo aggiunto come risorsa non elaborata. Il file di testo contiene testo come:

b) SE LA LEGGE APPLICABILE RICHIEDE QUALSIASI GARANZIA RIGUARDO AL SOFTWARE, TUTTE TALI GARANZIE SONO LIMITATE A DURATA A NOVANTA (90) GIORNI DALLA DATA DI CONSEGNA.

(c) NESSUNA INFORMAZIONE O CONSIGLIO ORALE O SCRITTO FORNITO DA VIRTUAL ORIENTEERING, DAI SUOI ​​RIVENDITORI, DISTRIBUTORI, AGENTI O DIPENDENTI POTRÀ CREARE UNA GARANZIA O IN QUALSIASI MODO AUMENTARE LA PORTATA DI QUALSIASI GARANZIA QUI FORNITA.

(d) (solo USA) ALCUNI STATI NON CONSENTONO L'ESCLUSIONE DI GARANZIE IMPLICITE, PERTANTO L'ESCLUSIONE DI CUI SOPRA POTREBBE NON ESSERE APPLICABILE. QUESTA GARANZIA TI CONFERISCE DIRITTI LEGALI SPECIFICI E PUOI AVERE INOLTRE ALTRI DIRITTI LEGALI CHE VARIANO DA STATO A STATO.

Sul mio schermo ho un layout come questo:

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

Il codice per leggere la risorsa raw è:

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

Il testo viene mostrato ma dopo ogni riga ottengo uno strano carattere [] Come posso rimuovere quel carattere? Penso che sia New Line.

SOLUZIONE DI LAVORO

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
Suggerimento: puoi annotare il tuo parametro rawRes con @RawRes in modo che Android Studio si aspetti le risorse non elaborate.
Roel

La soluzione funzionante dovrebbe essere pubblicata come risposta, dove può essere votata.
LarsH

Risposte:


65

Cosa succede se si utilizza un BufferedReader basato su caratteri invece di InputStream basato su byte?

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

Non dimenticare che readLine()salta le nuove righe!


162

Puoi usare questo:

    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
Non sono sicuro che Inputstream.available () sia la scelta corretta qui, piuttosto leggi n in un ByteArrayOutputStream fino a n == -1.
ThomasRS

15
Questo potrebbe non funzionare per grandi risorse. Dipende dalla dimensione del buffer di lettura del flusso di input e potrebbe restituire solo una parte della risorsa.
d4n3

6
@ d4n3 ha ragione, la documentazione del metodo disponibile del flusso di input afferma: "Restituisce un numero stimato di byte che possono essere letti o ignorati senza bloccare per ulteriori input. Si noti che questo metodo fornisce una garanzia così debole da non essere molto utile in pratica "
ozba

Guarda i documenti Android per InputStream.available. Se ho capito bene dicono che non dovrebbe essere usato per questo scopo. Chi avrebbe pensato che fosse così difficile leggere il contenuto di uno stupido file ...
anhoppe

2
E non dovresti catturare l'eccezione generale. Cattura invece IOException.
alcsan

30

Se usi IOUtils da apache "commons-io" è ancora più semplice:

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

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

Esperto di:

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

Gradle:

'commons-io:commons-io:2.4'

1
Cosa devo importare per utilizzare IOUtils?
UTENTE


8
Per gradle: compilare "commons-io: commons-io: 2.1"
JustinMorris

9
Ma in generale, importare librerie di terze parti esterne per evitare di scrivere altre 3 righe di codice .. sembra un eccessivo.
milosmns

12

Bene con Kotlin puoi farlo solo in una riga di codice:

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

O anche dichiarare la funzione di estensione:

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

E poi usalo subito:

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

Sei un angelo.
Robert Liberatore

Questa era l'unica cosa che ha funzionato per me! Grazie!
fuomag9

Bello! Hai reso la mia giornata!
cesards

3

Piuttosto fallo in questo modo:

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

Dal punto di attività , aggiungere

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

o da un caso di test , aggiungi

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

E osserva la tua gestione degli errori: non intercettare e ignorare le eccezioni quando le tue risorse devono esistere o qualcosa è (molto?) Sbagliato.


Devi chiudere lo stream aperto da openRawResource()?
Alex Semeniuk

Non lo so, ma questo è certamente standard. Aggiornare gli esempi.
ThomasRS

2

Questo è un altro metodo che funzionerà sicuramente, ma non riesco a leggere più file di testo da visualizzare in più visualizzazioni di testo in una singola attività, chiunque può aiutare?

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 puoi farlo in modo simile come

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

Ecco un mix di soluzioni di weekens e Vovodroid.

È più corretto della soluzione di Vovodroid e più completo della soluzione di 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

Ecco un metodo semplice per leggere il file di testo dalla cartella 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();
}

2

Ecco un'implementazione 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.Per prima cosa crea una cartella Directory e chiamala raw all'interno della cartella res 2.crea un file .txt all'interno della cartella della directory raw che hai creato in precedenza e dagli un nome qualsiasi, ad es. Articles.txt .... 3.copia e incolla il testo che vuoi all'interno del file .txt che hai creato "articoli.txt" 4.non dimenticare di includere una visualizzazione di testo nel tuo 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();
}

Spero abbia funzionato!


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());
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.