web-dev-qa-db-fra.com

Comment faire une copie d'un fichier dans Android?

Dans mon application, je veux enregistrer une copie d'un certain fichier avec un nom différent (que je reçois de l'utilisateur)

Dois-je vraiment ouvrir le contenu du fichier et l'écrire dans un autre fichier?

Quelle est la meilleure façon de le faire?

160
A S

Pour copier un fichier et le sauvegarder dans votre chemin de destination, vous pouvez utiliser la méthode ci-dessous.

public static void copy(File src, File dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dst);
        try {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

Sur l’API 19+, vous pouvez utiliser Java Automatic Resource Management:

public static void copy(File src, File dst) throws IOException {
    try (InputStream in = new FileInputStream(src)) {
        try (OutputStream out = new FileOutputStream(dst)) {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        }
    }
}
300
Rakshi

Vous pouvez également utiliser FileChannel pour copier un fichier. Il pourrait être plus rapide que la méthode de copie par octet lors de la copie d'un fichier volumineux Vous ne pouvez pas l'utiliser si votre fichier est supérieur à 2 Go cependant.

public void copy(File src, File dst) throws IOException {
    FileInputStream inStream = new FileInputStream(src);
    FileOutputStream outStream = new FileOutputStream(dst);
    FileChannel inChannel = inStream.getChannel();
    FileChannel outChannel = outStream.getChannel();
    inChannel.transferTo(0, inChannel.size(), outChannel);
    inStream.close();
    outStream.close();
}
117
NullNoname

Ceux-ci ont bien fonctionné pour moi

public static void copyFileOrDirectory(String srcDir, String dstDir) {

    try {
        File src = new File(srcDir);
        File dst = new File(dstDir, src.getName());

        if (src.isDirectory()) {

            String files[] = src.list();
            int filesLength = files.length;
            for (int i = 0; i < filesLength; i++) {
                String src1 = (new File(src, files[i]).getPath());
                String dst1 = dst.getPath();
                copyFileOrDirectory(src1, dst1);

            }
        } else {
            copyFile(src, dst);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void copyFile(File sourceFile, File destFile) throws IOException {
    if (!destFile.getParentFile().exists())
        destFile.getParentFile().mkdirs();

    if (!destFile.exists()) {
        destFile.createNewFile();
    }

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(sourceFile).getChannel();
        destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom(source, 0, source.size());
    } finally {
        if (source != null) {
            source.close();
        }
        if (destination != null) {
            destination.close();
        }
    }
}
15
Bojan Kseneman

Extension Kotlin pour cela

fun File.copyTo(file: File) {
    inputStream().use { input ->
        file.outputStream().use { output ->
            input.copyTo(output)
        }
    }
}
12
Dima Rostopira

C'est simple sur Android O (API 26), comme vous le voyez:

  @RequiresApi(api = Build.VERSION_CODES.O)
  public static void copy(File Origin, File dest) throws IOException {
    Files.copy(Origin.toPath(), dest.toPath());
  }
5
Lee

Voici une solution qui ferme les flux d’entrée/sortie en cas d’erreur lors de la copie. Cette solution utilise les méthodes Apache Commons IO IOUtils pour la copie et le traitement de la fermeture des flux.

    public void copyFile(File src, File dst)  {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(src);
            out = new FileOutputStream(dst);
            IOUtils.copy(in, out);
        } catch (IOException ioe) {
            Log.e(LOGTAG, "IOException occurred.", ioe);
        } finally {
            IOUtils.closeQuietly(out);
            IOUtils.closeQuietly(in);
        }
    }
4
SBerg413

Beaucoup plus simple maintenant avec Kotlin:

 File("originalFileDir", "originalFile.name")
            .copyTo(File("newCopyFileName", "newFile.name"), true)

trueoufalse sert à écraser le fichier de destination

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/Java.io.-file/copy-to.html

1
Blundell
                    FileInputStream fis=null;
                    FileOutputStream fos=null;
                    try {
                        fis = new FileInputStream(from);
                        fos=new FileOutputStream(to);
                        byte[] by=new byte[fis.available()];
                        int len;
                        while((len=fis.read(by))>0){
                            fos.write(by,0,len);
                        }
                    }catch (Throwable t){
                        Toast.makeText(context,t.toString(),Toast.LENGTH_LONG).show();
                    }
                    finally {
                        if(fis!=null) {
                            try {
                                fis.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                                Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
                            }
                        }
                        if(fos!=null) {
                            try {
                                fos.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                                Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
                            }
                        }
                    }
0
Tarasantan