83 votes

Android : Comment lire un fichier en octets ?

Je suis en train d'essayer de récupérer le contenu d'un fichier en octets dans une application Android. J'ai obtenu le fichier sur la carte SD et maintenant je veux obtenir le fichier sélectionné en octets. J'ai cherché sur Google mais sans succès. S'il vous plaît aidez

Voici le code pour obtenir les fichiers avec une extension. À travers cela, j'obtiens les fichiers et les affiche dans un spinner. Lors de la sélection d'un fichier, je veux obtenir le fichier en octets.

private List getListOfFiles(String path) {

   File files = new File(path);

   FileFilter filter = new FileFilter() {

      private final List exts = Arrays.asList("jpeg", "jpg", "png", "bmp", "gif","mp3");

      public boolean accept(File pathname) {
         String ext;
         String path = pathname.getPath();
         ext = path.substring(path.lastIndexOf(".") + 1);
         return exts.contains(ext);
      }
   };

   final File [] filesFound = files.listFiles(filter);
   List list = new ArrayList();
   if (filesFound != null && filesFound.length > 0) {
      for (File file : filesFound) {
         list.add(file.getName());
      }
   }
   return list;
}

138voto

idiottiger Points 3398

Ici c'est un simple:

File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
    BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
    buf.read(bytes, 0, bytes.length);
    buf.close();
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Ajouter la permission dans manifest.xml:

9 votes

Notez que buf.read() pourrait ne pas lire le nombre d'octets que vous demandez. Voir la javadoc ici : [docs.oracle.com/javase/6/docs/api/java/io/…](http://docs.oracle.com/javase/6/docs/api/java/io/BufferedInputStream.html#read(byte[]), int, int)

1 votes

N'oubliez pas dans le manifeste.

1 votes

Si vous allez lire l'intégralité du fichier en une seule fois, il est inutile d'envelopper le FileInputStream dans un BufferedInputStream - en effet, le faire va utiliser plus de mémoire et ralentir les choses car les données seront copiées inutilement.

27voto

Renaud Boulard Points 679

La solution la plus simple aujourd'hui est d'utiliser Apache common io :

http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FileUtils.html#readFileToByteArray(java.io.File)

byte bytes[] = FileUtils.readFileToByteArray(photoFile)

Le seul inconvénient est d'ajouter cette dépendance dans votre build.gradle app :

implementation 'commons-io:commons-io:2.5'

+ 1562 Compte des méthodes

24voto

lase Points 828

Étant donné que la méthode acceptée BufferedInputStream#read ne garantit pas de tout lire, au lieu de suivre moi-même les tailles des buffers, j'ai utilisé cette approche :

    byte bytes[] = new byte[(int) file.length()];
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    DataInputStream dis = new DataInputStream(bis);
    dis.readFully(bytes);

Bloque jusqu'à ce qu'une lecture complète soit terminée, et ne nécessite pas d'imports supplémentaires.

4 votes

Cela m'a vraiment beaucoup aidé.

0 votes

Pourquoi BufferedInputStream#read ne garantit-il pas de tout lire ? J'ai lu la documentation et je n'ai rien trouvé à propos de ce 'problème'.

0 votes

Beaucoup plus facile et direct. Merci

22voto

Siavash Points 406

Voici une solution qui garantit que le fichier entier sera lu, qui ne nécessite aucune bibliothèque et est efficace:

byte[] fullyReadFileToBytes(File f) throws IOException {
    int size = (int) f.length();
    byte bytes[] = new byte[size];
    byte tmpBuff[] = new byte[size];
    FileInputStream fis= new FileInputStream(f);;
    try {

        int read = fis.read(bytes, 0, size);
        if (read < size) {
            int remain = size - read;
            while (remain > 0) {
                read = fis.read(tmpBuff, 0, remain);
                System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
                remain -= read;
            }
        }
    }  catch (IOException e){
        throw e;
    } finally {
        fis.close();
    }

    return bytes;
}

REMARQUE: cela suppose que la taille du fichier est inférieure à MAX_INT bytes, vous pouvez ajouter une gestion pour cela si vous le souhaitez.

1 votes

Merci. Remplacez 'jsonFile' par 'f'.

0 votes

Vous rendez les choses très confuses en appelant la taille du buffer et la taille du fichier par le même nom : "size". De cette façon, vous aurez une taille de buffer égale à la taille du fichier, ce qui signifie qu'aucun buffer ne sera créé et votre boucle ne sera jamais exécutée.

0 votes

@FlorianB L'espoir est que la boucle ne soit jamais exécutée. dans le meilleur des cas, le fichier entier sera lu lors du premier appel à fis.read(bytes, 0, size);... la boucle est là au cas où le fichier serait trop gros et que le système ne lirait pas tout le fichier, auquel cas nous entrons dans la boucle et lisons le reste dans des appels consécutifs à fis.read(). file.read() ne garantit pas que tous les octets qui lui ont été demandés peuvent être lus en un seul appel, et la valeur de retour est le nombre d'octets EFFECTIVEMENT lus.

4voto

thefiscster510 Points 213

Si vous voulez utiliser la méthode openFileInput à partir d'un Context pour cela, vous pouvez utiliser le code suivant.

Ceci créera un BufferArrayOutputStream et ajoutera chaque octet à mesure qu'il est lu depuis le fichier.

/**
 * 
 *     Crée un InputStream pour un fichier en utilisant le Context spécifié
 *     et renvoie les octets lus à partir du fichier.
 * 
 *
 * @param context Le contexte à utiliser.
 * @param file Le fichier à lire.
 * @return Le tableau d'octets lus à partir du fichier, ou null si aucun fichier n'a été trouvé.
 */
public static byte[] read(Context context, String file) throws IOException {
    byte[] ret = null;

    if (context != null) {
        try {
            InputStream inputStream = context.openFileInput(file);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            int nextByte = inputStream.read();
            while (nextByte != -1) {
                outputStream.write(nextByte);
                nextByte = inputStream.read();
            }

            ret = outputStream.toByteArray();

        } catch (FileNotFoundException ignored) { }
    }

    return ret;
}

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