Wie kann ich Dateien und Verzeichnisse auf SD programmgesteuert verschieben, kopieren und löschen?

91

Ich möchte Dateien und Verzeichnisse auf der SD-Karte programmgesteuert verschieben, kopieren und löschen. Ich habe eine Google-Suche durchgeführt, konnte aber nichts Nützliches finden.

Tony
quelle

Antworten:

26

Verwenden Sie Standard - Java - I / O . Verwenden Sie Environment.getExternalStorageDirectory()diese Option , um zum Stammverzeichnis des externen Speichers zu gelangen (bei einigen Geräten handelt es sich um eine SD-Karte).

CommonsWare
quelle
Diese kopieren den Inhalt von Dateien, kopieren die Datei jedoch nicht wirklich - dh nicht kopierte Metadaten des Dateisystems ... Ich möchte eine Möglichkeit, dies (wie eine Shell cp) zu tun , um ein Backup zu erstellen, bevor ich eine Datei überschreibe. Ist es möglich?
Sanjay Manohar
9
Tatsächlich ist der relevanteste Teil der Standard-Java-E / A, java.nio.file, unter Android (API-Level 21) leider nicht verfügbar.
Corwin.amber
1
@CommonsWare: Können wir pragmatisch von SD auf private Dateien zugreifen? oder eine private Datei löschen?
Saad Bilal
@SaadBilal: Eine SD - Karte ist in der Regel Wechselspeicher , und Sie haben keine willkürlichen Zugriff auf Dateien auf Wechselspeicher über das Dateisystem.
CommonsWare
3
Mit der Veröffentlichung von Android 10 Scoping Storage wurde die neue Norm und alle Methoden zum Ausführen von Operationen mit Dateien haben sich ebenfalls geändert. Die Vorgehensweise von java.io funktioniert nicht mehr, es sei denn, Sie fügen "RequestLagacyStorage" mit dem Wert "true" in Ihr Manifest ein Die Methode Environment.getExternalStorageDirectory () wird ebenfalls beraubt
Mofor Emmanuel
158

Legen Sie die richtigen Berechtigungen im Manifest fest

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

Unten finden Sie eine Funktion, mit der Sie Ihre Datei programmgesteuert verschieben können

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

}

Um die Datei zu löschen, verwenden Sie

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

Kopieren

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
quelle
9
Vergessen Sie nicht, die Berechtigungen im Manifest festzulegen. <Verwendet-Berechtigung android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy
5
Vergessen Sie auch nicht, am Ende von inputPath und outputPath einen Schrägstrich einzufügen. Beispiel: / sdcard / NOT / sdcard
CONvid19
Ich habe versucht zu verschieben, aber ich kann nicht. Dies ist mein Code moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna
3
Vergessen Sie auch nicht, diese auf einem Hintergrund-Thread über AsyncTask oder einen Handler usw.
auszuführen
1
@DanielLeahy Wie kann ich sicherstellen, dass die Datei erfolgreich kopiert wurde und dann nur die Originaldatei löschen?
Rahulrr2602
141

Datei bewegen:

File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
WonderSoftwares
quelle
31
Ein Kopf hoch; "Beide Pfade befinden sich auf demselben Einhängepunkt. Unter Android stoßen Anwendungen am wahrscheinlichsten auf diese Einschränkung, wenn sie versuchen, zwischen internem Speicher und einer SD-Karte zu kopieren."
Zyamys
renameToscheitert ohne jede Erklärung
sasha199568
Seltsamerweise wird dadurch anstelle einer Datei ein Verzeichnis mit dem gewünschten Namen erstellt. Irgendwelche Ideen dazu? Die Datei 'von' ist lesbar und beide befinden sich auf der SD-Karte.
Xarlymg89
37

Funktion zum Verschieben von Dateien:

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
quelle
Welche Änderungen sind erforderlich, um die Datei zu kopieren?
BlueMango
2
@ BlueMango Entfernen Sie Zeile 10file.delete()
Peter Tran
Dieser Code funktioniert nicht für große Dateien wie 1 GB oder 2 GB.
Vishal Sojitra
@ Vishal Warum nicht?
LarsH
Ich denke, @Vishal bedeutet, dass das Kopieren und Löschen einer großen Datei viel mehr Speicherplatz und Zeit erfordert als das Verschieben dieser Datei.
LarsH
19

Löschen

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

Überprüfen Sie diesen Link für die obige Funktion.

Kopieren

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

}

Bewegung

Verschieben ist nichts. Kopieren Sie einfach den Ordner von einem Speicherort an einen anderen und löschen Sie den Ordner es ist

Manifest

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Duggu
quelle
11
  1. Berechtigungen:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. Stammordner der SD-Karte abrufen:

    Environment.getExternalStorageDirectory()
  3. Datei löschen: Dies ist ein Beispiel zum Löschen aller leeren Ordner in einem Stammordner:

    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. Datei kopieren:

    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. Datei verschieben = Quelldatei kopieren + löschen

Ken
quelle
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
quelle
6
File.renameTo funktioniert nur auf demselben Dateisystem-Volume. Außerdem sollten Sie das Ergebnis von renameTo überprüfen.
MyDogTom
5

Kopieren Sie die Datei mit Square's Okio :

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

Wenn Sie Guava verwenden, können Sie Files.move (von, nach) verwenden.

MyDogTom
quelle
Die Verbindung ist unterbrochen.
LarsH
1
@LarsH Ich habe den Link zu Guava JavaDoc behoben.
MyDogTom
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
quelle
1

Um eine Datei zu verschieben, kann diese API verwendet werden, aber Sie benötigen mindestens 26 als API-Ebene -

Datei bewegen

Wenn Sie jedoch ein Verzeichnis verschieben möchten, gibt es keine Unterstützung, sodass dieser native Code verwendet werden kann

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

Datei mit Kotlin verschieben. Die App muss über die Berechtigung verfügen, eine Datei in das Zielverzeichnis zu schreiben.

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

Datei oder Ordner verschieben:

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
quelle