Làm thế nào để di chuyển, sao chép và xóa các tệp và thư mục trên SD theo chương trình?


91

Tôi muốn lập trình di chuyển, sao chép và xóa các tệp và thư mục trên thẻ SD. Tôi đã thực hiện tìm kiếm trên Google nhưng không tìm thấy bất kỳ điều gì hữu ích.

Câu trả lời:


26

Sử dụng Java I / O tiêu chuẩn . Sử dụng Environment.getExternalStorageDirectory()để truy cập thư mục gốc của bộ nhớ ngoài (trên một số thiết bị, là thẻ SD).


Chúng sao chép nội dung của tệp nhưng không thực sự sao chép tệp - tức là siêu dữ liệu hệ thống lưu trữ không được sao chép ... Tôi muốn có một cách để thực hiện việc này (như shell cp) để tạo bản sao lưu trước khi ghi đè tệp. Nó có khả thi không?
Sanjay Manohar

9
Trên thực tế, phần liên quan nhất của Java I / O tiêu chuẩn, java.nio.file, rất tiếc là không có trên Android (API cấp 21).
corwin.amber

1
@CommonsWare: Chúng ta có thể truy cập các tệp riêng tư từ SD một cách thực dụng không? hoặc xóa bất kỳ tệp riêng tư nào?
Saad Bilal

@SaadBilal: Thẻ SD thường là bộ nhớ di động và bạn không có quyền truy cập tùy ý vào các tệp trên bộ nhớ di động thông qua hệ thống tệp.
CommonsWare

3
với việc phát hành bộ nhớ theo phạm vi android 10 đã trở thành tiêu chuẩn mới và tất cả các Phương thức thực hiện thao tác với tệp cũng đã thay đổi, các cách thực hiện của java.io sẽ không còn hoạt động trừ khi bạn thêm "RequestLagacyStorage" với giá trị "true" trong Tệp kê khai của mình Method Environment.getExternalStorageDirectory () cũng bị
mô tả

158

đặt các quyền chính xác trong tệp kê khai

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

bên dưới là một hàm sẽ di chuyển tệp của bạn theo chương trình

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

}

Để xóa tệp sử dụng

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

Sao chép

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
Đừng quên đặt quyền trong tệp kê khai <use-allow android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel Leahy

5
Ngoài ra, đừng quên thêm một dấu gạch chéo vào cuối inputPath và outputPath, Ví dụ: / sdcard / NOT / sdcard
CONvid. 19

tôi đã cố gắng di chuyển nhưng tôi không thể. đây là mã của tôi moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna

3
Ngoài ra, đừng quên để thực hiện những trên một sợi nền qua AsyncTask hoặc một Handler vv
w3bshark

1
@DanielLeahy Làm thế nào để đảm bảo rằng tệp đã được sao chép thành công và sau đó chỉ xóa tệp gốc?
Rahulrr2602

142

Di chuyển tệp tin:

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

31
A hướng lên; "Cả hai đường dẫn đều nằm trên cùng một điểm gắn kết. Trên Android, các ứng dụng có nhiều khả năng gặp phải hạn chế này nhất khi cố gắng sao chép giữa bộ nhớ trong và thẻ SD."
zyamys

renameTothất bại mà không cần bất kỳ lời giải thích
sasha199568

Thật kỳ lạ, điều này tạo ra một thư mục với tên mong muốn, thay vì một tệp. Bất kỳ ý tưởng về nó? Tệp 'từ' có thể đọc được và cả hai tệp này đều nằm trong thẻ SD.
xarlymg89

37

Chức năng để di chuyển tệp:

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

}

Điều này cần sửa đổi gì để SAO CHÉP tệp?
BlueMango

3
@BlueMango Xóa dòng 10file.delete()
Peter Tran,

Mã này sẽ không hoạt động đối với tệp lớn như tệp 1 gb hoặc 2 gb.
Vishal Sojitra

@Vishal Tại sao không?
LarsH

Tôi đoán @Vishal có nghĩa là việc sao chép và xóa một tệp lớn đòi hỏi nhiều không gian đĩa và thời gian hơn là di chuyển tệp đó.
LarsH

19

Xóa bỏ

public static void deleteRecursive(File fileOrDirectory) {

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

    fileOrDirectory.delete();

    }

kiểm tra liên kết này cho chức năng trên.

Sao chép

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

}

Di chuyển

di chuyển không có gì chỉ là sao chép thư mục này sang vị trí khác sau đó xóa thư mục chứa

rõ ràng

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

11
  1. Quyền:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. Nhận thư mục gốc thẻ SD:

    Environment.getExternalStorageDirectory()
  3. Xóa tệp: đây là ví dụ về cách xóa tất cả các thư mục trống trong thư mục gốc:

    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. Sao chép tệp:

    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. Di chuyển tệp = sao chép + xóa tệp nguồn


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 chỉ hoạt động trên cùng một ổ đĩa hệ thống tệp. Ngoài ra, bạn nên kiểm tra kết quả của renameTo.
MyDogTom

5

Sao chép tệp bằng Okio của 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

Để di chuyển một tệp, api này có thể được sử dụng nhưng bạn cần atleat 26 là cấp api -

Di chuyển tệp tin

Nhưng nếu bạn muốn di chuyển thư mục, không có hỗ trợ nào ở đó nên mã gốc này có thể được sử dụng

    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

Di chuyển tệp bằng kotlin. Ứng dụng phải có quyền ghi tệp trong thư mục đích.

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

0

Di chuyển tệp hoặc thư mục:

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();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.