129 votes

Android lit le texte du fichier de ressources brutes

J'ai un fichier texte ajouté en tant que ressource brute. Le fichier texte contient du texte comme :

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.

Sur mon écran, j'ai une disposition comme celle-ci :

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

Le code pour lire la ressource brute est :

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

Le texte s'affiche, mais après chaque ligne, j'obtiens les caractères étranges suivants [] . Comment puis-je supprimer ces caractères ? Je pense que c'est un saut de ligne.

3 votes

Conseil : vous pouvez annoter votre paramètre rawRes avec @RawRes afin qu'Android Studio s'attende à des ressources brutes.

0 votes

La solution de travail doit être publiée en tant que réponse, où elle peut être votée.

164voto

Vovodroid Points 757

Vous pouvez utiliser ceci :

    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 votes

Je ne suis pas sûr que l'Inputstream.available() soit le bon choix ici, il faut plutôt lire n dans un ByteArrayOutputStream jusqu'à ce que n == -1.

15 votes

Cela peut ne pas fonctionner pour les grandes ressources. Elle dépend de la taille du tampon de lecture du flux d'entrée et pourrait ne renvoyer qu'une partie de la ressource.

6 votes

@d4n3 a raison, la documentation de la méthode input stream available indique : "Renvoie un nombre estimé d'octets qui peuvent être lus ou sautés sans bloquer pour plus d'entrée. Notez que cette méthode fournit une garantie si faible qu'elle n'est pas très utile en pratique"

66voto

weekens Points 2685

Que se passe-t-il si vous utilisez un BufferedReader basé sur des caractères au lieu d'un InputStream basé sur des octets ?

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

N'oubliez pas que readLine() saute les nouvelles lignes !

32voto

tbraun Points 773

Si vous utilisez IOUtils de apache "commons-io", c'est encore plus facile :

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

Dépendances : 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 votes

Que dois-je importer pour utiliser IOUtils ?

1 votes

Bibliothèque Apache commons-io ( commons.apache.org/proper/commons-io ). Ou si vous utilisez Maven ( mvnrepository.com/artifact/commons-io/commons-io ).

8 votes

Pour gradle : compilez "commons-io:commons-io:2.1".

4voto

ThomasRS Points 5705

Je préfère le faire de cette façon :

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

D'un Activité , ajouter

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

ou d'un cas de test , ajouter

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

Et surveillez votre gestion des erreurs - ne récupérez pas et n'ignorez pas les exceptions lorsque vos ressources doivent exister ou que quelque chose ne va pas (vraiment ?).

0 votes

Avez-vous besoin de fermer un flux ouvert par openRawResource() ?

0 votes

Je ne sais pas, mais c'est certainement la norme. Mise à jour des exemples.

2voto

borislemke Points 366

Il s'agit d'une autre méthode qui fonctionnera certainement, mais je n'arrive pas à lire plusieurs fichiers texte pour les afficher dans plusieurs vues de texte dans une seule activité, quelqu'un peut m'aider ?

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X