Fichier de ressources brutes de lecture de texte Android

123

Les choses sont simples mais ne fonctionnent pas comme prévu.

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

b) SI LA LOI APPLICABLE EXIGE DES GARANTIES EN CE QUI CONCERNE LE LOGICIEL, TOUTES CES GARANTIES SONT LIMITÉES EN DURÉE À NEUF (90) JOURS À PARTIR DE LA DATE DE LIVRAISON.

(c) AUCUNE INFORMATION OU CONSEIL ORAL OU ÉCRIT FOURNI PAR VIRTUAL ORIENTEERING, SES CONCESSIONNAIRES, DISTRIBUTEURS, AGENTS OU EMPLOYÉS NE CRÉERONT DE GARANTIE OU D'AUGMENTER DE TOUTE MANIÈRE LA PORTÉE DE TOUTE GARANTIE FOURNIE AUX PRÉSENTES.

(d) (États-Unis uniquement) CERTAINS ÉTATS NE PERMETTENT PAS L'EXCLUSION DE GARANTIES IMPLICITES, PAR CONSÉQUENT, L'EXCLUSION CI-DESSUS PEUT NE PAS S'APPLIQUER À VOUS. CETTE GARANTIE VOUS DONNE DES DROITS LÉGAUX SPÉCIFIQUES ET VOUS POUVEZ ÉGALEMENT AVOIR D'AUTRES DROITS JURIDIQUES QUI VARIENT D'UN ÉTAT À L'AUTRE.

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 est affiché mais après chaque ligne, j'obtiens un caractère étrange [] Comment puis-je supprimer ce caractère? Je pense que c'est New Line.

SOLUTION DE TRAVAIL

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
la source
3
Astuce: vous pouvez annoter votre paramètre rawRes avec @RawRes afin qu'Android Studio attende des ressources brutes.
Roel le
La solution de travail doit être publiée en tant que réponse, où elle peut être votée.
LarsH

Réponses:

65

Que faire si vous utilisez un BufferedReader basé sur des caractères au lieu de InputStream basé sur des octets?

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

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

weekens
la source
162

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.");
    }
Vovodroid
la source
5
Je ne suis pas sûr que Inputstream.available () soit le bon choix ici, lisez plutôt n dans un ByteArrayOutputStream jusqu'à n == -1.
ThomasRS
15
Cela peut ne pas fonctionner pour de grandes ressources. Cela dépend de la taille du tampon de lecture du flux d'entrée et ne peut renvoyer qu'une partie de la ressource.
d4n3
6
@ d4n3 a raison, la documentation de la méthode disponible pour le flux d'entrée indique: "Renvoie un nombre estimé d'octets qui peuvent être lus ou ignorés sans blocage pour plus d'entrée. Notez que cette méthode fournit une garantie si faible qu'elle n'est pas très utile dans pratique "
ozba
Consultez la documentation Android pour InputStream. Disponible. Si je comprends bien, ils disent qu'il ne devrait pas être utilisé à cette fin. Qui avait pensé que c'était si difficile de lire le contenu d'un fichier stupide ...
anhoppe
2
Et vous ne devriez pas attraper une exception générale. Attrapez IOException à la place.
alcsan
30

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

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'
tbraun
la source
1
Que dois-je importer pour utiliser IOUtils?
UTILISATION du
1
Bibliothèque Apache commons-io ( commons.apache.org/proper/commons-io ). Ou si vous utilisez Maven ( mvnrepository.com/artifact/commons-io/commons-io ).
tbraun
8
Pour gradle: compilez "commons-io: commons-io: 2.1"
JustinMorris
9
Mais en général, importer des bibliothèques tierces externes pour éviter d'écrire 3 lignes de code supplémentaires ... semble exagéré.
milosmns
12

Eh bien, avec Kotlin, vous pouvez le faire en une seule ligne de code:

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

Ou même déclarer la fonction d'extension:

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

Et puis utilisez-le tout de suite:

val txtFile = resources.getRawTextFile(R.raw.rawtextsample)
Arsenius
la source
Tu es un ange.
Robert Liberatore
C'était la seule chose qui fonctionnait pour moi! Je vous remercie!
fuomag9
Agréable! Tu as fait ma journée!
cesards le
3

Faites-le plutôt 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"));
}

À partir d'une activité , ajoutez

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

ou à partir d'un cas de test , ajoutez

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

Et surveillez votre gestion des erreurs - n'attrapez pas et n'ignorez pas les exceptions lorsque vos ressources doivent exister ou que quelque chose ne va (très?) Pas.

ThomasRS
la source
Avez-vous besoin de fermer le flux ouvert par openRawResource()?
Alex Semeniuk
Je ne sais pas, mais c'est certainement la norme. Mise à jour des exemples.
ThomasRS
2

C'est une autre méthode qui fonctionnera certainement, mais je ne peux pas la faire lire plusieurs fichiers texte à afficher dans plusieurs vues de texte dans une seule activité, n'importe qui peut vous 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();
}
Borislemke
la source
2

@borislemke vous pouvez le faire de la même manière, comme

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
la source
2

Voici un mélange de solutions de week-end et de Vovodroid.

Elle est plus correcte que la solution de Vovodroid et plus complète que la solution de 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
    }
Alcsan
la source
2

Voici une méthode simple pour lire le fichier texte à partir du dossier brut :

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
la source
2

Voici une implémentation dans 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 hein
la source
1

1.Créez d'abord un dossier de répertoire et nommez-le raw dans le dossier res 2. créez un fichier .txt dans le dossier de répertoire raw que vous avez créé précédemment et donnez-lui un nom, par exemple, articles.txt .... 3. copiez et collez le texte que vous voulez dans le fichier .txt que vous avez créé "articles.txt" 4. n'oubliez pas d'inclure une vue de texte dans votre 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();
}

J'espère que cela a fonctionné!

Frankrnz
la source
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
la source