2012-07-18 3 views
1

현재 Android 용 기본 파일 브라우저에서 작업 중입니다. 필자는 파일 복사를위한 작업 버전을 가지고 있지만 디렉토리를 통해 파일을 복사합니다. 복사를 시작하기 전에 모든 파일의 전체 크기를 찾을 수 있도록 변경하여보다 나은 진행률 표시 줄을 돕고 싶습니다.Android - 파일 복사 (모두 동시에)

디렉토리의 전체 크기와 모든 내용을 찾을 수있는 다른 방법이 있습니까?

다음은 현재 버전입니다. 이 문제를 변경하는 데 문제가 있습니다. 배열 목록을 사용하여 시도했지만 끝에 파일을 복사하려고하면 잘못된 순서로 복사하려고합니다.

public void copyDirectory(File sourceLocation , File targetLocation) throws IOException { 
     if (sourceLocation.isDirectory()) { 
      if (!targetLocation.exists() && !targetLocation.mkdirs()) { 
       throw new IOException("Cannot create directory: " + targetLocation.getAbsolutePath()); 
      } 

      String[] children = sourceLocation.list(); 
      for (int i = 0; i < children.length; i++) { 
       copyDirectory(new File(sourceLocation, children[i]), 
         new File(targetLocation, children[i])); 
      } 
     } else {     
      File directory = targetLocation.getParentFile(); 
      if (directory != null && !directory.exists() && !directory.mkdirs()) { 
       throw new IOException("Cannot create directory: " + directory.getAbsolutePath()); 
      } 

      FileInputStream in = new FileInputStream(sourceLocation); 
      FileOutputStream out = new FileOutputStream(targetLocation); 

      long fileLength = sourceLocation.length(); 

      byte[] buf = new byte[1024]; 
      long total = 0; 
      int len; 
      while ((len = in.read(buf)) > 0) { 
       out.write(buf, 0, len); 
       total += len; 
       publishProgress((int) (total * 100/fileLength)); 
      } 
      in.close(); 
      out.close(); 
     } 
    } 

솔루션

jtwigg의 대답도 작동합니다. 방금 찾은 해결책을 추가 할 것이라고 생각했습니다. 제 질문에 대답 할 수 없으니 여기에 적어 두겠습니다.

디렉토리의 모든 파일을 반복하고 누적 합계를 유지하는 것이 효과가있는 것 같습니다. 실제로 크기를 반복하고 파일을 실제로 복사해야합니다. copyDirectory()를 호출하기 전에 복사 할 파일이나 디렉토리로 getDirectorySize()를 호출하면됩니다.

private void getDirectorySize(File sourceLocation) throws IOException { 
     if (sourceLocation.isDirectory()) { 
      String[] children = sourceLocation.list(); 
      for (int i = 0; i < children.length; i++) { 
       getDirectorySize(new File(sourceLocation, children[i])); 
      } 
     } else { 
      totalFileSize += sourceLocation.length(); 
     } 
} 

기능은 글로벌 긴 totalFileSize을 필요로하고 요구되는 모든 교체하는 것입니다

publishProgress((int) (total * 100/fileLength)); 

로 : 내가 제대로 이해하면

publishProgress((int) (total * 100/totalFileSize)); 
+0

당신은'for' 루프에서 이것을하려고합니까? – gobernador

답변

2

, 당신이 원하는 디렉토리에있는 모든 파일의 전체 크기를 찾은 다음 복사하십시오. 당신은 단지 소스와 목적지를 모두 보유 할 PendingFile 클래스/구조를 필요

public void beginCopy(File source, File destination) 
{ 
    ArrayList<PendingFile> filesToCopy = new ArrayList<PendingFile>(); 
    long totalSize = copyDirectory(source, destination, filesToCopy); 
    // totalsize now contains the size of all the files 
    // files to copy now contains a list of source and destination files 

    // now modifying your copy method we can copy all the files 
    long totalThusFar = 0; 
    for (PendingFile pending : filesToCopy) 
    { 
     FileInputStream in = new FileInputStream(pending.source); 
     FileOutputStream out = new FileOutputStream(pending.destination); 

     long fileLength = sourceLocation.length(); 

     byte[] buf = new byte[1024]; 
     int len; 
     while ((len = in.read(buf)) > 0) { 
      out.write(buf, 0, len); 
      totalThusFar += len; 
      publishProgress((int) (total * 100/totalsize)); 
     } 
     in.close(); 
     out.close(); 
    } 
} 

: 나는 같은 것을 다른 함수를 만들 것입니다. 그것은 아마도 바로 작동하지 않도록

public long copyDirectory(File sourceLocation , File targetLocation, ArrayList list) throws IOException { 
    if (sourceLocation.isDirectory()) { 
     if (!targetLocation.exists() && !targetLocation.mkdirs()) { 
      throw new IOException("Cannot create directory: " + targetLocation.getAbsolutePath()); 
     } 

     String[] children = sourceLocation.list(); 
     long totalSize = 0; 
     for (int i = 0; i < children.length; i++) { 
      totalSize += copyDirectory(new File(sourceLocation, children[i]), 
        new File(targetLocation, children[i]), list); 
      return totalSize; 
     } 
    } else {     
     File directory = targetLocation.getParentFile(); 
     if (directory != null && !directory.exists() && !directory.mkdirs()) { 
      throw new IOException("Cannot create directory: " + directory.getAbsolutePath()); 
     } 

     list.add(new PendingFile(sourceLocation, targetLocation)); 
     return sourceLocation.length; 
    } 
} 

내가 지금이 모든 것을 썼다 그러나 나는 당신이이 작업을 얻을 수 있어야한다고 생각 :이처럼 복사 방법에 ArrayList의에 추가됩니다. 행운을 빕니다!

+0

답장을 보내 주셔서 감사합니다. 그래, 전체 크기를 얻는 유일한 방법은 다른 함수를 만들고 디렉토리를 두 ​​번 반복하는 것입니다. 내가 기다리고있는 동안 방금 다른 기능을 만들었습니다. 한 번 루프를 돌릴 수있는 방법이 있기를 바랬습니다. 나는 내가 생각해 낸 기능을 올릴 것이다. 누군가가 잘하면 도움이 될 수 있습니다. 다시 한 번 감사드립니다. – enifeder

관련 문제