¿Cómo mover, copiar y eliminar archivos y directorios en SD mediante programación?

91

Quiero mover, copiar y eliminar archivos y directorios en la tarjeta SD mediante programación. Hice una búsqueda en Google pero no pude encontrar nada útil.

Tony
fuente

Respuestas:

26

Utilice E / S estándar de Java . Úselo Environment.getExternalStorageDirectory()para acceder a la raíz del almacenamiento externo (que, en algunos dispositivos, es una tarjeta SD).

CommonsWare
fuente
Estos copian el contenido de los archivos, pero en realidad no copian el archivo, es decir, no se copian los metadatos del sistema de archivo ... Quiero una forma de hacer esto (como un shell cp) para hacer una copia de seguridad antes de sobrescribir un archivo. ¿Es posible?
Sanjay Manohar
9
En realidad, la parte más relevante del estándar Java I / O, java.nio.file, desafortunadamente no está disponible en Android (API nivel 21).
corwin.amber
1
@CommonsWare: ¿Podemos acceder a archivos privados desde SD de forma pragmática? o borrar algún archivo privado?
Saad Bilal
@SaadBilal: Una tarjeta SD suele ser un almacenamiento extraíble y no tiene acceso arbitrario a los archivos en el almacenamiento extraíble a través del sistema de archivos.
CommonsWare
3
con el lanzamiento de Android 10, el almacenamiento con alcance se convirtió en la nueva norma y todos los métodos para realizar operaciones con archivos también han cambiado, las formas de hacer java.io ya no funcionarán a menos que agregue "RequestLagacyStorage" con el valor "true" en su manifiesto el método Environment.getExternalStorageDirectory () también está depricado
Mofor Emmanuel
158

establecer los permisos correctos en el manifiesto

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

a continuación se muestra una función que moverá su archivo mediante programación

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());
    }

}

Para eliminar el uso del archivo

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());
    }
}

Copiar

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
fuente
9
No olvide configurar los permisos en el manifiesto <uses-allow android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy
5
Además, no olvide agregar una barra al final de inputPath y outputPath, por ejemplo: / sdcard / NOT / sdcard
CONvid19
Traté de moverme pero no puedo. Este es mi código moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna
3
Además, no olvide ejecutarlos en un hilo en segundo plano a través de AsyncTask o un controlador, etc.
w3bshark
1
@DanielLeahy ¿Cómo asegurarse de que el archivo se haya copiado correctamente y luego solo eliminar el archivo original?
Rahulrr2602
142

Mover archivo:

File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
WonderSoftwares
fuente
31
Un aviso; "Ambas rutas están en el mismo punto de montaje. En Android, es más probable que las aplicaciones alcancen esta restricción al intentar copiar entre el almacenamiento interno y una tarjeta SD".
zyamys
renameTofalla sin ninguna explicación
sasha199568
Curiosamente, esto crea un directorio con el nombre deseado, en lugar de un archivo. ¿Alguna idea al respecto? El archivo 'desde' es legible y ambos están en la tarjeta SD.
xarlymg89
37

Función para mover archivos:

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
fuente
¿Qué modificaciones necesita esto para COPIAR el archivo?
BlueMango
3
@BlueMango Quitar la línea 10file.delete()
Peter Tran
Este código no funcionará para archivos grandes como archivos de 1 gb o 2 gb.
Vishal Sojitra
@Vishal ¿Por qué no?
LarsH
Supongo que @Vishal significa que copiar y eliminar un archivo grande requiere mucho más espacio y tiempo en disco que mover ese archivo.
LarsH
19

Eliminar

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

Consulte este enlace para ver la función anterior.

Copiar

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();
}

}

Moverse

mover no es nada, simplemente copie la carpeta de una ubicación a otra y luego elimine la carpeta que es

manifiesto

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
duggu
fuente
11
  1. Permisos:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. Obtener la carpeta raíz de la tarjeta SD:

    Environment.getExternalStorageDirectory()
  3. Eliminar archivo: este es un ejemplo de cómo eliminar todas las carpetas vacías en una carpeta raíz:

    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. Copiar archivo:

    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. Mover archivo = copiar + eliminar archivo fuente

Conocido
fuente
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
fuente
6
File.renameTo funciona solo en el mismo volumen del sistema de archivos. También debe verificar el resultado de renameTo.
MyDogTom
5

Copie el archivo usando Okio de Square :

BufferedSink bufferedSink = Okio.buffer(Okio.sink(destinationFile));
bufferedSink.writeAll(Okio.source(sourceFile));
bufferedSink.close();
LetItRock
fuente
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
fuente
3

Si está usando Guava, puede usar Files.move (desde, hasta)

MyDogTom
fuente
El vínculo está roto.
LarsH
1
@LarsH He arreglado el enlace a Guava JavaDoc.
MyDogTom
1

Android de Xamarin

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
fuente
1

Para mover un archivo, se puede usar esta api, pero necesita atleat 26 como nivel de api -

mover archivo

Pero si desea mover el directorio, no hay soporte, por lo que se puede usar este código nativo

    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
fuente
1

Mover archivo usando kotlin. La aplicación debe tener permiso para escribir un archivo en el directorio de destino.

@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
fuente
0

Mover archivo o carpeta:

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
fuente