105

I want to programmatically move, copy and delete files and directories on SD card. I've done a Google search but couldn't find anything useful.

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Tony
  • 1,603
  • 3
  • 21
  • 40

16 Answers16

174

set the correct permissions in the manifest

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

below is a function that will programmatically move your file

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

}

To Delete the file use

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

To copy

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

}
rsc
  • 10,348
  • 5
  • 39
  • 36
Daniel Leahy
  • 1,953
  • 2
  • 11
  • 7
  • 9
    Don't forget to set the permissions in the manifest – Daniel Leahy Jul 04 '12 at 11:29
  • 6
    Also, don't forget to add a slash at the end of inputPath and outputPath, Ex: /sdcard/ NOT /sdcard – Pedro Lobito Jul 27 '13 at 07:05
  • i tried to move but i cant.this is my code moveFile(file.getAbsolutePath(),myfile, Environment.getExternalStorageDirectory()+ "/CopyEcoTab/" ); – Meghna Mar 26 '14 at 17:31
  • Depending on how you use this method, you may not require `` so make sure you don't add this permission unnecessarily. – ban-geoengineering Jan 29 '15 at 13:24
  • Very helpful, I suggest just dropping this code into a static `FileHelper` class and making your life easier. Thanks – Aggressor Jun 03 '15 at 20:55
  • File is moved but not its metadata, especially lastmodified date is changed – chin87 Feb 22 '16 at 09:32
  • This below permission is also required from android M – Ken May 24 '16 at 12:42
  • 3
    Also, don't forget to execute these on a background thread via AsyncTask or a Handler, etc. – w3bshark Sep 06 '16 at 19:41
  • Good contribution user469020. Made some edits. Must be weary of Pokemon exception handling ;) See number 2 of https://blog.codinghorror.com/new-programming-jargon/ – the_new_mr Nov 14 '16 at 14:52
  • 1
    @DanielLeahy How to make sure that the file has been copied successfully and then only delete the original file? – Rahulrr2602 Jul 21 '17 at 06:34
  • @DanielLeahy What should we pass inside *inputFile* while using *moveFile* because i am giving *fileName* at that point and it's always giving me *FileNotFoundException*. Can you please guide through that ? – Jay Rathod Feb 16 '18 at 06:49
  • Don't forget to prompt the user for WRITE_EXTERNAL_STORAGE permission – AtomicBoolean Oct 02 '18 at 15:57
  • `[input / output]Path + File.separator + inputFile` if you don't want to use `new File([input / output]Path, inputFile)` or you end up with some amalgamation of the directory and file name in the folder above where it should be moved. – Abandoned Cart Nov 23 '21 at 03:16
153

Move file:

File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
Faizan Mubasher
  • 4,427
  • 11
  • 45
  • 81
WonderSoftwares
  • 2,800
  • 1
  • 15
  • 21
  • 35
    A heads up; "Both paths be on the same mount point. On Android, applications are most likely to hit this restriction when attempting to copy between internal storage and an SD card." – zyamys Jan 22 '15 at 00:28
  • `renameTo` fails without any explanation – sasha199568 Mar 19 '18 at 12:42
  • Strangely, this creates a directory with the desired name, instead of a file. Any ideas about it? The File 'from' is readable, and both of them are in the SD card. – xarlymg89 Oct 22 '18 at 14:36
39

Function for moving files:

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
  • 721
  • 1
  • 7
  • 11
28

Use standard Java I/O. Use Environment.getExternalStorageDirectory() to get to the root of external storage (which, on some devices, is an SD card).

Cassie
  • 5,223
  • 3
  • 22
  • 34
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • These copy the contents of files but don't really copy the file - i.e. filing system metadata not copied... I want a way to do this (like shell `cp`) to make a backup before I overwrite a file. Is it possible? – Sanjay Manohar Aug 05 '11 at 01:14
  • 9
    Actually the most relevant part of the standard Java I/O, java.nio.file, is unfortunately not available on Android (API level 21). – corwin.amber Dec 22 '14 at 02:37
  • 1
    @CommonsWare: Can we access private files from SD pragmatically? or delete any private file? – Saad Bilal Feb 22 '17 at 09:44
  • @SaadBilal: An SD card is usually [removable storage](https://commonsware.com/blog/2014/04/09/storage-situation-removable-storage.html), and you do not have arbitrary access to files on removable storage via the filesystem. – CommonsWare Feb 22 '17 at 12:18
  • 4
    with the release of android 10 scoped storage became the new norm and all Methods of doing operations with files has also changed, the java.io ways of doing will no longer work unless you add "RequestLagacyStorage" with the value "true" in your Manifest the Method Environment.getExternalStorageDirectory() is also depricated – Mofor Emmanuel Apr 29 '20 at 18:50
  • 1
    This answer is not usable anymore in 2021. – Satyajit Jul 06 '21 at 17:16
23

Delete

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

check this link for above function.

Copy

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

}

Move

move is nothing just copy the folder one location to another then delete the folder thats it

manifest

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Community
  • 1
  • 1
duggu
  • 37,851
  • 12
  • 116
  • 113
  • 1
    This worked like a charm. Tried in API 25 to 29. Used for migrating my files from top level storage to app directory to implement scoped storage. – Satyajit Jul 06 '21 at 17:17
12
  1. Permissions:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  2. Get SD card root folder:

    Environment.getExternalStorageDirectory()
    
  3. Delete file: this is an example on how to delete all empty folders in a root folder:

    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. Copy file:

    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. Move file = copy + delete source file

Pang
  • 9,564
  • 146
  • 81
  • 122
Ken
  • 1,303
  • 13
  • 15
7

Copy file using Square's Okio:

BufferedSink bufferedSink = Okio.buffer(Okio.sink(destinationFile));
bufferedSink.writeAll(Okio.source(sourceFile));
bufferedSink.close();
LetItRock
  • 280
  • 3
  • 8
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
  • 4,784
  • 2
  • 32
  • 24
  • 6
    [File.renameTo](http://docs.oracle.com/javase/7/docs/api/java/io/File.html#renameTo(java.io.File)) works only on the same file system volume. Also you should check result of renameTo. – MyDogTom Feb 03 '15 at 09:56
6

In Kotlin you can use copyTo() extension function,

sourceFile.copyTo(destFile, true)
Ahmet B.
  • 1,290
  • 10
  • 20
3

If you are using Guava, you can use Files.move(from, to)

MyDogTom
  • 4,486
  • 1
  • 28
  • 41
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());
        }
    }
J.R
  • 2,113
  • 19
  • 21
2

Moving file using kotlin. App has to have permission to write a file in destination directory.

@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
  • 4,549
  • 3
  • 20
  • 20
2

Move File or Folder:

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
  • 4,437
  • 42
  • 39
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
  • 8,397
  • 4
  • 64
  • 80
1

To move a file this api can be used but you need atleat 26 as api level -

move file

But if you want to move directory no support is there so this native code can be used

    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
  • 597
  • 6
  • 21
0

You can use this folder with file path & destination path

public void copyFile(String sourcePath, String destinationPath) throws IOException {
    FileInputStream inStream = new FileInputStream(sourcePath);
    FileOutputStream outStream = new FileOutputStream(destinationPath);
    FileChannel inChannel = inStream.getChannel();
    FileChannel outChannel = outStream.getChannel();
    inChannel.transferTo(0, inChannel.size(), outChannel);
    inStream.close();
    outStream.close();
}