Comment déplacer, copier et supprimer par programme des fichiers et des répertoires sur SD?

91

Je souhaite déplacer, copier et supprimer par programmation des fichiers et des répertoires sur la carte SD. J'ai fait une recherche sur Google mais je n'ai rien trouvé d'utile.

Tony
la source

Réponses:

26

Utilisez les E / S Java standard . Utilisez Environment.getExternalStorageDirectory()pour accéder à la racine du stockage externe (qui, sur certains appareils, est une carte SD).

CommonsWare
la source
Ceux-ci copient le contenu des fichiers mais ne copient pas vraiment le fichier - c'est-à-dire que les métadonnées du système de classement ne sont pas copiées ... Je veux un moyen de faire cela (comme le shell cp) pour faire une sauvegarde avant d'écraser un fichier. C'est possible?
Sanjay Manohar
9
En fait, la partie la plus pertinente de l'E / S Java standard, java.nio.file, n'est malheureusement pas disponible sur Android (niveau d'API 21).
corwin.amber
1
@CommonsWare: Pouvons-nous accéder aux fichiers privés de SD de manière pragmatique? ou supprimer un fichier privé?
Saad Bilal
@SaadBilal: Une carte SD est généralement un stockage amovible , et vous n'avez pas d'accès arbitraire aux fichiers sur le stockage amovible via le système de fichiers.
CommonsWare
3
avec la sortie d'Android 10, le stockage à portée est devenu la nouvelle norme et toutes les méthodes d'opérations avec des fichiers ont également changé, les méthodes de java.io ne fonctionneront plus à moins que vous n'ajoutiez "RequestLagacyStorage" avec la valeur "true" dans votre manifeste la méthode Environment.getExternalStorageDirectory () est également dépréciée
Mofor Emmanuel
158

définir les autorisations correctes dans le manifeste

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

ci-dessous est une fonction qui déplacera votre fichier par programmation

private void moveFile(String inputPath, String inputFile, String outputPath) {

    InputStream in = null;
    OutputStream out = null;
    try {

        //create output directory if it doesn't exist
        File dir = new File (outputPath); 
        if (!dir.exists())
        {
            dir.mkdirs();
        }


        in = new FileInputStream(inputPath + inputFile);        
        out = new FileOutputStream(outputPath + inputFile);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;

            // write the output file
            out.flush();
        out.close();
        out = null;

        // delete the original file
        new File(inputPath + inputFile).delete();  


    } 

         catch (FileNotFoundException fnfe1) {
        Log.e("tag", fnfe1.getMessage());
    }
          catch (Exception e) {
        Log.e("tag", e.getMessage());
    }

}

Pour supprimer le fichier, utilisez

private void deleteFile(String inputPath, String inputFile) {
    try {
        // delete the original file
        new File(inputPath + inputFile).delete();  
    }
    catch (Exception e) {
        Log.e("tag", e.getMessage());
    }
}

Copier

private void copyFile(String inputPath, String inputFile, String outputPath) {

    InputStream in = null;
    OutputStream out = null;
    try {

        //create output directory if it doesn't exist
        File dir = new File (outputPath); 
        if (!dir.exists())
        {
            dir.mkdirs();
        }


        in = new FileInputStream(inputPath + inputFile);        
        out = new FileOutputStream(outputPath + inputFile);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;

            // write the output file (You have now copied the file)
            out.flush();
        out.close();
        out = null;        

    }  catch (FileNotFoundException fnfe1) {
        Log.e("tag", fnfe1.getMessage());
    }
            catch (Exception e) {
        Log.e("tag", e.getMessage());
    }

}
Daniel Leahy
la source
9
N'oubliez pas de définir les autorisations dans le manifeste <uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy
5
N'oubliez pas non plus d'ajouter une barre oblique à la fin de inputPath et outputPath, Ex: / sdcard / NOT / sdcard
CONvid19
J'ai essayé de bouger mais je ne peux pas. C'est mon code moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna
3
N'oubliez pas non plus de les exécuter sur un thread d'arrière-plan via AsyncTask ou un gestionnaire, etc.
w3bshark
1
@DanielLeahy Comment s'assurer que le fichier a été copié avec succès et supprimer uniquement le fichier d'origine?
Rahulrr2602
142

Déplacer le fichier:

File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
WonderSoftwares
la source
31
A en tête; "Les deux chemins se trouvent sur le même point de montage. Sur Android, les applications sont plus susceptibles de rencontrer cette restriction lorsqu'elles tentent de copier entre le stockage interne et une carte SD."
zyamys
renameToéchoue sans aucune explication
sasha199568
Curieusement, cela crée un répertoire avec le nom souhaité, au lieu d'un fichier. Des idées à ce sujet? Le fichier «de» est lisible, et les deux sont sur la carte SD.
xarlymg89
37

Fonction pour déplacer des fichiers:

private void moveFile(File file, File dir) throws IOException {
    File newFile = new File(dir, file.getName());
    FileChannel outputChannel = null;
    FileChannel inputChannel = null;
    try {
        outputChannel = new FileOutputStream(newFile).getChannel();
        inputChannel = new FileInputStream(file).getChannel();
        inputChannel.transferTo(0, inputChannel.size(), outputChannel);
        inputChannel.close();
        file.delete();
    } finally {
        if (inputChannel != null) inputChannel.close();
        if (outputChannel != null) outputChannel.close();
    }

}
Asivura
la source
De quelles modifications a-t-il besoin pour COPIER le fichier?
BlueMango
3
@BlueMango Supprimer la ligne 10file.delete()
Peter Tran
Ce code ne fonctionnera pas pour les gros fichiers tels que les fichiers de 1 Go ou 2 Go.
Vishal Sojitra
@Vishal Pourquoi pas?
LarsH
Je suppose que @Vishal signifie que la copie et la suppression d'un fichier volumineux nécessitent beaucoup plus d'espace disque et de temps que le déplacement de ce fichier.
LarsH
19

Supprimer

public static void deleteRecursive(File fileOrDirectory) {

 if (fileOrDirectory.isDirectory())
    for (File child : fileOrDirectory.listFiles())
        deleteRecursive(child);

    fileOrDirectory.delete();

    }

vérifiez ce lien pour la fonction ci-dessus.

Copie

public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
    throws IOException {

if (sourceLocation.isDirectory()) {
    if (!targetLocation.exists()) {
        targetLocation.mkdir();
    }

    String[] children = sourceLocation.list();
    for (int i = 0; i < sourceLocation.listFiles().length; i++) {

        copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
                new File(targetLocation, children[i]));
    }
} else {

    InputStream in = new FileInputStream(sourceLocation);

    OutputStream out = new FileOutputStream(targetLocation);

    // Copy the bits from instream to outstream
    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();
}

}

Bouge toi

déplacer n'est rien, simplement copier le dossier d'un emplacement à un autre puis supprimer le dossier qui le correspond

manifeste

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
duggu
la source
11
  1. Autorisations:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. Obtenez le dossier racine de la carte SD:

    Environment.getExternalStorageDirectory()
  3. Supprimer le fichier: voici un exemple sur la façon de supprimer tous les dossiers vides dans un dossier racine:

    public static void deleteEmptyFolder(File rootFolder){
        if (!rootFolder.isDirectory()) return;
    
        File[] childFiles = rootFolder.listFiles();
        if (childFiles==null) return;
        if (childFiles.length == 0){
            rootFolder.delete();
        } else {
            for (File childFile : childFiles){
                deleteEmptyFolder(childFile);
            }
        }
    }
  4. Copier un fichier:

    public static void copyFile(File src, File dst) throws IOException {
        FileInputStream var2 = new FileInputStream(src);
        FileOutputStream var3 = new FileOutputStream(dst);
        byte[] var4 = new byte[1024];
    
        int var5;
        while((var5 = var2.read(var4)) > 0) {
            var3.write(var4, 0, var5);
        }
    
        var2.close();
        var3.close();
    }
  5. Déplacer le fichier = copier + supprimer le fichier source

Ken
la source
6
File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
xnagyg
la source
6
File.renameTo ne fonctionne que sur le même volume de système de fichiers. Vous devez également vérifier le résultat de renameTo.
MyDogTom
5

Copiez le fichier en utilisant Okio de Square :

BufferedSink bufferedSink = Okio.buffer(Okio.sink(destinationFile));
bufferedSink.writeAll(Okio.source(sourceFile));
bufferedSink.close();
LetItRock
la source
3
/**
     * Copy the local DB file of an application to the root of external storage directory
     * @param context the Context of application
     * @param dbName The name of the DB
     */
    private void copyDbToExternalStorage(Context context , String dbName){

        try {
            File name = context.getDatabasePath(dbName);
            File sdcardFile = new File(Environment.getExternalStorageDirectory() , "test.db");//The name of output file
            sdcardFile.createNewFile();
            InputStream inputStream = null;
            OutputStream outputStream = null;
            inputStream = new FileInputStream(name);
            outputStream = new FileOutputStream(sdcardFile);
            byte[] buffer = new byte[1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            inputStream.close();
            outputStream.flush();
            outputStream.close();
        }
        catch (Exception e) {
            Log.e("Exception" , e.toString());
        }
    }
JR
la source
3

Si vous utilisez Guava, vous pouvez utiliser Files.move (de, à)

MyDogTom
la source
Le lien est rompu.
LarsH
1
@LarsH J'ai corrigé le lien vers Guava JavaDoc.
MyDogTom le
1

Xamarin Android

public static bool MoveFile(string CurrentFilePath, string NewFilePath)
{
    try
    {
        using (var f = new File(CurrentFilePath))
        using (var i = new FileInputStream(f))
        using (var o = new FileOutputStream(NewFilePath))
        {
            i.Channel.TransferTo(0, i.Channel.Size(), o.Channel);
            f.Delete();
        }

        return true;
    }
    catch { return false; }
}

public static bool CopyFile(string CurrentFilePath, string NewFilePath)
{
    try
    {
        using (var i = new FileInputStream(CurrentFilePath))
        using (var o = new FileOutputStream(NewFilePath))
            i.Channel.TransferTo(0, i.Channel.Size(), o.Channel);

        return true;
    }
    catch { return false; }
}

public static bool DeleteFile(string FilePath)
{
    try
    {
        using (var file = new File(FilePath))
            file.Delete();

        return true;
    }
    catch { return false; }
}
Pierre
la source
1

Pour déplacer un fichier, cette api peut être utilisée mais vous avez besoin de atleat 26 comme niveau api -

déplacer le fichier

Mais si vous souhaitez déplacer un répertoire, aucun support n'est disponible, ce code natif peut donc être utilisé

    import org.apache.commons.io.FileUtils;

    import java.io.IOException;
    import java.io.File;

    public class FileModule {

    public void moveDirectory(String src, String des) {
    File srcDir = new File(src);
    File destDir = new File(des);
     try {
        FileUtils.moveDirectory(srcDir,destDir);
    } catch (Exception e) {
      Log.e("Exception" , e.toString());
      }
    }

    public void deleteDirectory(String dir) {
      File delDir = new File(dir);
      try {
        FileUtils.deleteDirectory(delDir);
       } catch (IOException e) {
      Log.e("Exception" , e.toString());
      }
     }
    }
abby37
la source
1

Déplacement de fichier à l'aide de kotlin. L'application doit avoir l'autorisation d'écrire un fichier dans le répertoire de destination.

@Throws(FileNotFoundException::class, IOError::class)
private fun moveTo(source: File, dest: File, destDirectory: File? = null) {

    if (destDirectory?.exists() == false) {
        destDirectory.mkdir()
    }

    val fis = FileInputStream(source)
    val bufferLength = 1024
    val buffer = ByteArray(bufferLength)
    val fos = FileOutputStream(dest)
    val bos = BufferedOutputStream(fos, bufferLength)
    var read = fis.read(buffer, 0, read)
    while (read != -1) {
        bos.write(buffer, 0, read)
        read = fis.read(buffer) // if read value is -1, it escapes loop.
    }
    fis.close()
    bos.flush()
    bos.close()

    if (!source.delete()) {
        HLog.w(TAG, klass, "failed to delete ${source.name}")
    }
}
Brownsoo Han
la source
0

Déplacer un fichier ou un dossier:

public static void moveFile(File srcFileOrDirectory, File desFileOrDirectory) throws IOException {
    File newFile = new File(desFileOrDirectory, srcFileOrDirectory.getName());
    try (FileChannel outputChannel = new FileOutputStream(newFile).getChannel(); FileChannel inputChannel = new FileInputStream(srcFileOrDirectory).getChannel()) {
        inputChannel.transferTo(0, inputChannel.size(), outputChannel);
        inputChannel.close();
        deleteRecursive(srcFileOrDirectory);
    }
}

private static void deleteRecursive(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory())
        for (File child : Objects.requireNonNull(fileOrDirectory.listFiles()))
            deleteRecursive(child);
    fileOrDirectory.delete();
}
Ahamadullah Saikat
la source