IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Bases de l'écriture - lecture de fichiers en stockage interne


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2009
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 19
    Par défaut Bases de l'écriture - lecture de fichiers en stockage interne
    Bonjour,

    Pour mon application, j'ai besoin de stocker des données dans un fichier, afin de les transmettre en pièce jointe par mail. Etant plutot débutant, je fais des proto pour avancer pas à pas. Et je bute déjà sur la première étape consistant à stocker une chaîne de caractères dans un fichier, et ensuite l'ouvrir à nouveau pour lire et afficher son contenu. Ecriture et lecture dans deux activités différentes, tant qu'à faire. J'ai choisis à priori de créer le fichier dans le stockage interne, sachant qu'ensuite j'aurai à résoudre le problème de le rendre accessible à une autre application pour l'envoi par mail, mais celà me semble quand même être la meilleure solution car ces fichiers n'ont pas vocation à être utilisé ensuite sur le smartphone comme peut l'être une photo par exemple. J'ai prévu de les effacer une fois le mail envoyé.

    J'ai récupéré un code plusieurs fois qualifié de OK par leur utilisateur. Or chez moi il ne marche pas, malgré moultes essais. Le code qui cré le fichier dans la 1ère activité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
       public void creFichier(Context c) {
            String mot = "Hello world, this is crazy";
            FileOutputStream fos = null;
            OutputStreamWriter outStream = null;
     
            try {
                fos = c.openFileOutput("test.txt", c.MODE_PRIVATE);
                outStream = new OutputStreamWriter(fos);
                outStream.write(mot);
                outStream.close();
                Log.d("Control", "write ok");
            } catch (IOException e) {
                Log.d("Control", "write ko");
                Log.e("Controller", e.getMessage() + e.getLocalizedMessage() + e.getCause());
            }
        }
    Cette partie fonctionne car j'ai le bon message dans le log.

    Maintenant la lecture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
            String filename, read;
            final Context c = this.context;
            read = " ";
            filename = "test.txt";
     
            try {
                InputStream fis = c.openFileInput(filename);
                if (fis != null) {
                    InputStreamReader inputStream = new InputStreamReader(fis);
                    tFic.setText("Coucou");
                    BufferedReader buffRead = new BufferedReader(inputStream);
                    String receivStr = "";
                    StringBuilder stringB = new StringBuilder();
                    while ((receivStr = buffRead.readLine()) != null) {
                        stringB.append(receivStr);
                    }
                    read = stringB.toString();
                }
                fis.close();
     
                tFic.setText(read);
     
     
            } catch (Throwable t) {
                Log.d(MAIL_TAG, "Erreur IO");
                Log.e(MAIL_TAG, t.getMessage() + t.getLocalizedMessage() + t.getCause());
            }
    tFic étant un textView dans mon layout d'activité... Et là, j'ai le message dans le log exprimant clairement que le "try" est parti en erreur, à priori dès l'ouverture du fichier. (getMessage(), getLocalizedMessage() et getCause() renvoient null tous les trois)

    J'ai tenté par exemple de renseigner le nom du fichier avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MailActivity.this.getFilesDir().getAbsolutePath()+"/test.txt"
    , mais c'est pareil.

    Je n'ai plus de pistes de recherche...

    Quelqu'un a-t-il une idée de ce qui se passe ?

    Merci d'avance

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Déjà en faisant des Log corrects tu auras plus d'information:

    Au lieu de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Log.d(MAIL_TAG, "Erreur IO");
    Log.e(MAIL_TAG, t.getMessage() + t.getLocalizedMessage() + t.getCause());
    Faire simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Log.e(MAIL_TAG, "Erreur IO",t);
    C'est plus court et ça log correctement les exceptions.



    D'autre par la gestion du close() est pas vraiment correcte (bon il est rare quand on tombe dans le cas ou tous les streams sont utilisés, mais néanmoins...):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    BufferedReader reader = null;
    try {
         reader = new BufferedReader(c.openFileInput(filename));
         ...
         ...
         ...
    } catch (Throwable t) {
         Log.e(MAIL_TAG, "Erreur IO",t);
    } finally {
         if (reader != null) try { reader.close(); } catch (Exception ex) { Log.e(MAIL_TAG,"Failed to gracefully close reader !",ex); }
    }

    Quant à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MailActivity.this.getFilesDir().getAbsolutePath()+"/test.txt"
    Il fait exactement la même chose (Context.getFilesDir() renvoyant le répertoire ou sont stockés les fichier openFileOuput / openFileInput).
    Son but est d'obtenir un "File" à utiliser directement dans une autre partie du code qui n'aurait pas de "Context":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    File testFile = new File(MailActivity.this.getFilesDir().getAbsolutePath(),"test.txt"); // <= pas de '/' on sait jamais, c'est peut être pas / :D
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileInputStream(testFile));
        ...
    ....
    Maintenant ton utilisation de MailActivity.this me fait penser que tu n'es pas dans l'activité quand tu fais la lecture... Es-tu bien dans le thread UI ? Sinon c'est le setText() qui peut planter !

  3. #3
    Membre averti
    Inscrit en
    Février 2009
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 19
    Par défaut
    Tout d'abord merci de ton aide.

    Résultats suite à tes apports :

    - Je suis bien dans le thread UI. setText() m'affiche bien "coucou" si je le place avant openFileInput en premier dans le pavé try. Le log me montre que c'est bien openFileInput qui foire avec un java.lang.NullPointerException. En fait ce code est dans la méthode onClick() d'une classe MailActivity. Si j'utilise Context.getFilesDir(), j'ai une erreur à la compilation : non-static méthod getFilesDir can't be referenced from a static context. Alors que Nom_de-l-activite.this.GetFilesDir fonctionne...

    - Sur ta remarque à propos de la bonne pratique pour fermer le fichier : j'ai quand même un truc bizarre. Les objets créés dans le pavé try (que ce soit buffRead, ou fis dans mon code, ou reader dans ton exemple) ne sont pas visible dans le pavé finally...

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    [QUOTE=mac-gyver;8527731]Tout d'abord merci de ton aide.

    Résultats suite à tes apports :

    Le log me montre que c'est bien openFileInput qui foire avec un java.lang.NullPointerException.
    Si c'est sur la ligne du openFileInput, alors pas de problème... ça veut dire que "c" est null....
    D'ailleurs, je ne comprends pas trop la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    final Context c = this.context;
    Autant utiliser this.context dans ce cas non ?
    Que vaut this.context ? comment est-il initialisé ?

    En fait ce code est dans la méthode onClick() d'une classe MailActivity. Si j'utilise Context.getFilesDir(), j'ai une erreur à la compilation : non-static méthod getFilesDir can't be referenced from a static context. Alors que Nom_de-l-activite.this.GetFilesDir fonctionne...
    Si le code est dans le onClick de la classe MailActivity, alors la fonction "getFilesDir()" est directement utilisable (MailActivity étant je présume une activité, et donc ... un Context).
    (quand j'écris Context.getFilesDir() cela veut dire l'appel à la fonction getFilesDir() d'un contexte, et pas l'appel static...)

    Sur ta remarque à propos de la bonne pratique pour fermer le fichier : j'ai quand même un truc bizarre. Les objets créés dans le pavé try (que ce soit buffRead, ou fis dans mon code, ou reader dans ton exemple) ne sont pas visible dans le pavé finally...
    C'est pour ça que j'ai sorti la déclaration du BufferedReader do bloc try....
    A noter que sous Java-8 c'est encore plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    try(BufferedReader reader = new BuffererdReader(openFileInput("test.txt"))) { 
       ... le block try ...
    }
    // ET C'EST TOUT... Java se demerde pour le close

  5. #5
    Membre averti
    Inscrit en
    Février 2009
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 19
    Par défaut
    En attendant une réponse à mon dernier post, j'ai réussi à faire fonctionner le code à la fin de ce post. Mais ta réponse m'apporte un certain nombre d'explications à des problèmes que j'ai rencontré en essayant de faire fonctionner ce code.
    Dans mon cas, j'apprends en même temps java, et son implémentation dans android. Pour quelqu'un qui n'a pas programmé depuis vingt ans (sauf peut être un peu de html, VBscript par ci par là), et qui en est resté au Cobol, C, (même pas C++), Fortran, Pascal, et autres de cette époque, celà fait beaucoup de concepts à assimiler. J'ai rapidement éprouvé le besoin de pratiquer pour assimiler. Mais ce faisant, je mets généralement en oeuvre beaucoup de concepts. Et en voulant utiliser des codes postés sur le net, je me retrouve à devoir l'adapter d'un contexte à un autre, ce que je ne sais encore pas trés bien faire par manque de maîtrise de tous les concepts de base.

    Ta réponse m'amène aussi des explications qu'on ne trouve généralement pas dans les tuto ou autres ouvrages. Je vais les expérimenter de ce pas.

    Merci encore pour ton aide. Je vais maintenant m'employer à rendre ce code plus "dans les règles" à la lumière de tes explications (l'histoire du Context "c" par exemple, ou du close dans le finaly), et ensuite je passerai à l'objectif d'aprés : envoyer ce fichier par mail en pièce jointe. Ce qui me vaudra peut être de revenir si je n'y arrive pas.

    Le code qui marche. J'ai bien affiché dans le TextView ce que j'ai écris dans le fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
            String filename, read;
            read = " ";
            InputStreamReader inputStream;
     
            filename = this.getFilesDir()+"/at.pdf";
     
            Log.d(MAIL_TAG, "Fichier : " + filename);
     
            try {
                tFic.setText("Coucou");
     
                FileInputStream fis = new FileInputStream(filename);
     
                if (fis != null) {
     
                    inputStream = new InputStreamReader(fis);
                    BufferedReader buffRead = new BufferedReader(inputStream);
                    String receivStr = "";
                    StringBuilder stringB = new StringBuilder();
                    while ((receivStr = buffRead.readLine()) != null) {
                        stringB.append(receivStr);
                    }
                    read = stringB.toString();
                }
                fis.close();
     
                tFic.setText(read);
     
     
            } catch (Throwable t) {
                Log.e(MAIL_TAG, "Erreur IO",t);
            }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lecture/écriture dans un fichier
    Par benkunz dans le forum Langage
    Réponses: 3
    Dernier message: 10/04/2007, 11h35
  2. écriture/lecture dans des fichiers
    Par rafale001 dans le forum C
    Réponses: 14
    Dernier message: 02/03/2007, 16h59
  3. Réponses: 47
    Dernier message: 28/01/2007, 19h39
  4. lecture écriture dans un fichier
    Par poukill dans le forum C++
    Réponses: 9
    Dernier message: 23/05/2006, 11h02
  5. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo