SD'deki dosya ve dizinleri programlı olarak nasıl taşınır, kopyalar ve silerim?


94

SD karttaki dosya ve dizinleri programlı olarak taşımak, kopyalamak ve silmek istiyorum. Bir Google araması yaptım ancak yararlı hiçbir şey bulamadım.

Yanıtlar:


27

Standart Java I / O kullanın . Environment.getExternalStorageDirectory()Harici depolamanın (bazı cihazlarda bir SD kart olan) köküne ulaşmak için kullanın .


Bunlar dosyaların içeriğini kopyalar ancak dosyayı gerçekten kopyalamaz - yani dosyalama sistemi meta verileri kopyalanmaz ... Bunu yapmanın bir yolunu (kabuk gibi cp) bir dosyanın üzerine yazmadan önce bir yedekleme yapmak istiyorum. Mümkün mü?
Sanjay Manohar

9
Aslında standart Java I / O'nun en alakalı kısmı olan java.nio.file maalesef Android'de (API seviyesi 21) mevcut değil.
corwin.amber

1
@CommonsWare: SD'deki özel dosyalara pragmatik olarak erişebilir miyiz? veya herhangi bir özel dosyayı silinsin mi?
Saad Bilal

@SaadBilal: Bir SD kart genellikle çıkarılabilir depolamadır ve dosya sistemi aracılığıyla çıkarılabilir depolamadaki dosyalara keyfi erişiminiz yoktur.
CommonsWare

3
android 10 kapsamlı depolamanın piyasaya sürülmesiyle yeni norm haline geldi ve dosyalarla işlem yapmanın tüm Yöntemleri de değişti, Manifest'inize "true" değerine sahip "RequestLagacyStorage" eklemediğiniz sürece java.io'nun uygulama yöntemleri artık çalışmayacak Method Environment.getExternalStorageDirectory () de depricated
Mofor Emmanuel

161

manifestte doğru izinleri ayarlayın

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

Aşağıda, dosyanızı programlı olarak taşıyacak bir işlev bulunmaktadır

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

}

Dosyayı silmek için şunu kullanın:

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

Kopyalamak

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

}

9
Manifest <kullanım izni android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy,

5
Ayrıca, inputPath ve outputPath'in sonuna bir eğik çizgi eklemeyi unutmayın, Örn: / sdcard / NOT / sdcard
Pedro Lobito

taşımayı denedim ama cant.bu benim kodum moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna

3
Ayrıca, bunları bir arka plan iş parçacığında AsyncTask veya bir İşleyici vb. Aracılığıyla çalıştırmayı unutmayın.
w3bshark

1
@DanielLeahy Dosyanın başarıyla kopyalandığından nasıl emin olunur ve ardından yalnızca orijinal dosya silinir?
Rahulrr2602

142

Dosyayı taşı:

File from = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);

32
Bir uyarı; "Her iki yol da aynı bağlama noktasında. Android'de, uygulamalar büyük olasılıkla dahili depolama ile bir SD kart arasında kopyalama yapmaya çalışırken bu kısıtlamaya ulaşır."
zyamys

renameToherhangi bir açıklama olmadan başarısız
sasha199568

Garip bir şekilde, bu bir dosya yerine istenen ada sahip bir dizin oluşturur. Bununla ilgili herhangi bir fikrin var mı? 'Kimden' dosyası okunabilir ve her ikisi de SD karttadır.
xarlymg89

38

Dosyaları taşıma işlevi:

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

}

Dosyayı KOPYALAMAK için ne tür değişiklikler gerekiyor?
BlueMango

3
@BlueMango 10. satırı kaldırfile.delete()
Peter Tran

Bu kod, 1 gb veya 2 gb dosya gibi büyük dosyalar için çalışmayacaktır.
Vishal Sojitra

@Vishal Neden olmasın?
LarsH

Sanırım @Vishal, büyük bir dosyanın kopyalanması ve silinmesinin, o dosyayı taşımaktan çok daha fazla disk alanı ve zaman gerektirdiği anlamına geliyor.
LarsH

19

Sil

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

Yukarıdaki işlev için bu bağlantıyı kontrol edin .

Kopyala

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

}

Hareket

Hareket şey adildir diğerine klasör bir konum kopyalamak sonra klasör silmek thats it

belirgin

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

11
  1. İzinler:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  2. SD kart kök klasörünü alın:

    Environment.getExternalStorageDirectory()
    
  3. Dosyayı sil: Bu, bir kök klasördeki tüm boş klasörlerin nasıl silineceğine ilişkin bir örnektir:

    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. Dosya kopyala:

    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. Dosyayı taşı = kopyala + kaynak dosyayı sil


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

6
File.renameTo yalnızca aynı dosya sistemi biriminde çalışır. Ayrıca renameTo sonucunu da kontrol etmelisiniz.
MyDogTom

6

Square's Okio'yu kullanarak dosyayı kopyalayın :

BufferedSink bufferedSink = Okio.buffer(Okio.sink(destinationFile));
bufferedSink.writeAll(Okio.source(sourceFile));
bufferedSink.close();

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


2

Kotlin kullanarak dosya taşıma. Uygulama, hedef dizine dosya yazma iznine sahip olmalıdır.

@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}")
    }
}

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

1

Bir dosyayı taşımak için bu api kullanılabilir, ancak api seviyesi olarak atleat 26 gerekir -

dosyayı taşı

Ancak dizini taşımak istiyorsanız destek yoktur, bu nedenle bu yerel kod kullanılabilir

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

1

Dosya veya Klasörü Taşı:

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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.