จะย้ายคัดลอกและลบไฟล์และไดเร็กทอรีบน SD โดยทางโปรแกรมได้อย่างไร


93

ฉันต้องการย้ายคัดลอกและลบไฟล์และไดเร็กทอรีบนการ์ด SD โดยใช้โปรแกรม ฉันค้นหาโดย Google แล้ว แต่ไม่พบสิ่งที่เป็นประโยชน์

คำตอบ:


27

ใช้ Java I / Oมาตรฐาน ใช้Environment.getExternalStorageDirectory()เพื่อไปที่รูทของที่จัดเก็บข้อมูลภายนอก (ซึ่งในอุปกรณ์บางอย่างเป็นการ์ด SD)


สิ่งเหล่านี้คัดลอกเนื้อหาของไฟล์ แต่ไม่ได้คัดลอกไฟล์ - เช่นข้อมูลเมตาของระบบการจัดเก็บไม่ได้คัดลอก ... ฉันต้องการวิธีทำเช่นนี้ (เช่นเชลล์cp) เพื่อทำการสำรองข้อมูลก่อนที่ฉันจะเขียนทับไฟล์ เป็นไปได้ไหม?
Sanjay Manohar

9
อันที่จริงแล้วส่วนที่เกี่ยวข้องที่สุดของ Java I / O มาตรฐาน java.nio.file นั้นไม่สามารถใช้ได้บน Android (API ระดับ 21)
corwin.amber

1
@CommonsWare: เราสามารถเข้าถึงไฟล์ส่วนตัวจาก SD ในทางปฏิบัติได้หรือไม่? หรือลบไฟล์ส่วนตัว?
Saad Bilal

@SaadBilal: โดยปกติการ์ด SD จะเป็นที่เก็บข้อมูลแบบถอดได้และคุณไม่มีสิทธิ์เข้าถึงไฟล์ในที่เก็บข้อมูลแบบถอดได้โดยพลการผ่านระบบไฟล์
CommonsWare

3
ด้วยการเปิดตัวพื้นที่จัดเก็บข้อมูลที่มีขอบเขต android 10 กลายเป็นบรรทัดฐานใหม่และวิธีการทั้งหมดในการดำเนินการกับไฟล์ก็เปลี่ยนไปเช่นกันวิธีการทำ java.io จะไม่ทำงานอีกต่อไปเว้นแต่คุณจะเพิ่ม "RequestLagacyStorage" ด้วยค่า "จริง" ในไฟล์ Manifest ของคุณ Method Environment.getExternalStorageDirectory () ก็ถูกกีดกันเช่นกัน
Mofor Emmanuel

159

ตั้งค่าการอนุญาตที่ถูกต้องในรายการ

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

ด้านล่างนี้เป็นฟังก์ชันที่จะย้ายไฟล์ของคุณโดยทางโปรแกรม

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

}

ในการลบไฟล์ให้ใช้

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

เพื่อคัดลอก

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 <ใช้ - อนุญาต android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy

5
นอกจากนี้อย่าลืมเพิ่มเครื่องหมายทับที่ส่วนท้ายของ inputPath และ outputPath เช่น: / sdcard / NOT / sdcard
Pedro Lobito

ฉันพยายามที่จะย้าย แต่ฉันทำไม่ได้นี่คือรหัสของฉัน moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna

3
นอกจากนี้อย่าลืมเรียกใช้สิ่งเหล่านี้บนเธรดพื้นหลังผ่าน AsyncTask หรือ Handler ฯลฯ
w3bshark

1
@DanielLeahy จะแน่ใจได้อย่างไรว่าไฟล์ถูกคัดลอกสำเร็จแล้วลบเฉพาะไฟล์ต้นฉบับเท่านั้น?
Rahulrr2602

142

ย้ายไฟล์:

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

32
การบอกล่วงหน้าหรือเตือนล่วงหน้า; "เส้นทางทั้งสองอยู่บนจุดต่อเชื่อมเดียวกันใน Android แอปพลิเคชันมักจะประสบกับข้อ จำกัด นี้เมื่อพยายามคัดลอกระหว่างที่จัดเก็บข้อมูลภายในและการ์ด SD"
zyamys

renameToล้มเหลวโดยไม่มีคำอธิบายใด ๆ
sasha199568

น่าแปลกที่สิ่งนี้จะสร้างไดเร็กทอรีที่มีชื่อที่ต้องการแทนที่จะเป็นไฟล์ มีความคิดเกี่ยวกับเรื่องนี้หรือไม่? ไฟล์ 'จาก' สามารถอ่านได้และทั้งสองไฟล์อยู่ในการ์ด SD
xarlymg89

38

ฟังก์ชั่นสำหรับการย้ายไฟล์:

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

}

การปรับเปลี่ยนใดที่จำเป็นในการคัดลอกไฟล์
BlueMango

3
@BlueMango ลบบรรทัดที่ 10file.delete()
Peter Tran

รหัสนี้ใช้ไม่ได้กับไฟล์ขนาดใหญ่เช่นไฟล์ 1 gb หรือ 2 gb
Vishal Sojitra

@Vishal ทำไมไม่?
LarsH

ฉันเดาว่า @Vishal หมายความว่าการคัดลอกและลบไฟล์ขนาดใหญ่ต้องใช้เนื้อที่ดิสก์และเวลามากกว่าการย้ายไฟล์นั้น
LarsH

19

ลบ

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

ตรวจสอบลิงค์นี้สำหรับฟังก์ชันด้านบน

สำเนา

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

}

ย้าย

การย้ายไม่มีอะไรเพียงแค่คัดลอกโฟลเดอร์หนึ่งไปยังอีกตำแหน่งหนึ่งแล้วลบโฟลเดอร์นั้น

รายการ

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

11
  1. สิทธิ์:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  2. รับโฟลเดอร์รูทการ์ด SD:

    Environment.getExternalStorageDirectory()
    
  3. ลบไฟล์: นี่คือตัวอย่างวิธีการลบโฟลเดอร์ว่างทั้งหมดในโฟลเดอร์รูท:

    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. คัดลอกไฟล์:

    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. ย้ายไฟล์ = คัดลอก + ลบไฟล์ต้นฉบับ


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ทำงานบนไดรฟ์ข้อมูลระบบไฟล์เดียวกันเท่านั้น นอกจากนี้คุณควรตรวจสอบผลลัพธ์ของการเปลี่ยนชื่อเป็น
MyDogTom

6

คัดลอกไฟล์โดยใช้Okioของ Square :

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


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

ในการย้ายไฟล์ api นี้สามารถใช้ได้ แต่คุณต้อง atleat 26 เป็นระดับ api -

ย้ายไฟล์

แต่ถ้าคุณต้องการย้ายไดเร็กทอรีไม่มีการสนับสนุนดังนั้นจึงสามารถใช้โค้ดเนทีฟ

    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

การย้ายไฟล์โดยใช้ kotlin แอปต้องมีสิทธิ์ในการเขียนไฟล์ในไดเรกทอรีปลายทาง

@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

ย้ายไฟล์หรือโฟลเดอร์:

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();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.