SD에서 파일 및 디렉토리를 프로그래밍 방식으로 이동, 복사 및 삭제하는 방법은 무엇입니까?


91

프로그래밍 방식으로 SD 카드의 파일 및 디렉토리를 이동, 복사 및 삭제하고 싶습니다. Google 검색을 수행했지만 유용한 정보를 찾을 수 없습니다.

답변:


26

표준 Java I / O를 사용 합니다. Environment.getExternalStorageDirectory()외부 저장소 (일부 장치에서는 SD 카드)의 루트로 이동하는 데 사용 합니다.


이들은 파일의 내용을 복사하지만 실제로 파일을 복사하지는 않습니다. 즉, 파일링 시스템 메타 데이터가 복사되지 않았습니다 cp. 파일을 덮어 쓰기 전에 백업을 만들기 위해이 작업을 수행하는 방법 (예 : shell )을 원합니다 . 가능합니까?
Sanjay Manohar 2011-08-05

9
실제로 표준 Java I / O의 가장 관련성이 높은 부분 인 java.nio.file은 안타깝게도 Android (API 레벨 21)에서 사용할 수 없습니다.
corwin.amber

1
@CommonsWare : SD의 개인 파일에 실용적으로 액세스 할 수 있습니까? 또는 개인 파일을 삭제 하시겠습니까?
Saad Bilal

@SaadBilal : SD 카드는 일반적으로 이동식 저장소 이며 파일 시스템을 통해 이동식 저장소의 파일에 임의로 액세스 할 수 없습니다.
CommonsWare

3
Android 10 범위 저장소의 출시와 함께 새로운 표준이되었고 파일 작업을 수행하는 모든 메서드도 변경되었습니다. 매니페스트에 "true"값으로 "RequestLagacyStorage"를 추가하지 않으면 java.io 방식이 더 이상 작동하지 않습니다. 메서드 Environment.getExternalStorageDirectory ()는 또한 depricated한다
Mofor 엠마누엘

158

매니페스트에 올바른 권한 설정

     <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
매니페스트 <uses-permission android : name = "android.permission.WRITE_EXTERNAL_STORAGE"/>에서 권한을 설정하는 것을 잊지 마십시오
Daniel Leahy

5
또한 inputPath 및 outputPath 끝에 슬래시를 추가하는 것을 잊지 마십시오. 예 : / sdcard / NOT / sdcard
CONvid19

이동하려고했지만 cant. 이것은 내 코드입니다. moveFile (file.getAbsolutePath (), myfile, Environment.getExternalStorageDirectory () + "/ CopyEcoTab /");
Meghna 2014 년

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

31
A 헤드 업; "두 경로 모두 동일한 마운트 지점에 있습니다. Android에서 애플리케이션은 내부 저장소와 SD 카드간에 복사를 시도 할 때이 제한에 도달 할 가능성이 높습니다."
zyamys 2015 년

renameTo어떤 설명없이 실패
sasha199568

이상하게도 이것은 파일 대신 원하는 이름의 디렉토리를 생성합니다. 그것에 대한 아이디어가 있습니까? 'from'파일은 읽을 수 있으며 둘 다 SD 카드에 있습니다.
xarlymg89

37

파일 이동 기능 :

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 10 행 제거file.delete()
Peter Tran

이 코드는 1GB 또는 2GB 파일과 같은 큰 파일에는 작동하지 않습니다.
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 는 동일한 파일 시스템 볼륨에서만 작동합니다. 또한 renameTo의 결과를 확인해야합니다.
MyDogTom

5

Square의 Okio를 사용하여 파일 복사 :

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를 사용할 수 있지만 API 수준으로 atleat 26이 필요합니다.

파일 이동

그러나 디렉토리를 이동하려는 경우 지원이 없으므로이 기본 코드를 사용할 수 있습니다.

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

0

파일 또는 폴더 이동 :

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.