2012-04-20 2 views
2

Java 선물을 처음 사용하려고합니다. 일부 파일의 압축을 풀도록 클래스를 설정했습니다. 재귀 적으로 압축을 풀고 싶습니다. 왜냐하면 zip 파일을 포함하고있는 zip 파일이 있기 때문입니다.Java 선물을 사용하여 스레드 안전 수집 작업을 수행합니다.

나는 드라이브 클래스를 사용하여 호출 가능을 구현하는 Uncompressor 클래스를 인스턴스화합니다. Uncompressor는 압축이 풀리기 시작하고, 다른 .zip을 가로 지르면 자체 인스턴스를 생성하고 풀에 추가 한 다음 계속합니다. 여기 사이비 코드

From DriverClass: 

. 
. 
. 
ExecutorService pool = new Executors.newFixedThreadPool(4); 
Uncompressor uc = new Uncompressor(pool, compressedFile); 
Collection<File> files = uc.uncompress(); 
for(Future <Collection<File>> f : uc.futures) 
    files.addAll(f.get()); 
// at the end of this loop, files doesnt seem to hold all of my files 

그리고

내 uncompressor 클래스

public class Uncompressor implements Callable<Collection<File>> 
{ 
    public Set<Future<Collection<File>>> futures = new HashSet<Future<Collection<File>>>(); 
    File compressedFile; 
public Uncompressor(ExecutorService pool, File compressedFile) 
{ 
    this.pool = pool; 
    this.compressedFile = compressedFile; 
} 

public Collection<File> call() throws Exception[ 
    return uncompress(); 
} 

public Collection<File> uncompress() 
{ 
List<File> uncompressedFiles = new ArrayList<File>(); 
. 
.Loop 
.//Try to uncompress the file. If the archive entry is a zip file, do the following: 

    Callable<Collection<File>> callable = new Uncompressor(this.pool, archiveFileEntry); 
    Future f = pool.submit(callable); 
    futures.add(f); 

//else, add files to a collection here for returning 
uncompressedFiles.add(archiveFileEntry); 

.EndLoop 

return uncompressedFiles; 
. 
. 
} 

그래서 문제가, 내 DriverClass에있는 재귀에서 압축되지 않은 파일을 모두 보유해야하는 파일의 내 컬렉션 여기에 다이빙은 그 안에 모든 파일을 가지고있는 것 같습니다. 나는 미래로부터의 반환 가치를 얻는 것에 뭔가 잘못하고 있다고 생각한다. 클래스 멤버 변수 futures이 정의 된 방식 때문입니까?

은 1보다 큰 중첩의 깊이를 가지고있는 경우에 최상위 지퍼 지퍼를 포함하는 우편 번호를 포함, 즉 당신이

+0

예, 가능합니다. 그것은 zip 내의 모든 zip 번호 일 수 있습니다. 실제로는 – Derek

답변

3

귀하의 코드가 작동하지 않습니다 감사합니다. 이 경우 최상위 Uncompressor는 최하위 수준의 zip 파일에 대한 미래가 없습니다.

재귀 유형 작업 분류에 더 적합하므로 ForkJoinPool을 사용하는 것이 좋습니다.

--Caller-- 

Collection<File> alluncompressedFiles = new HashSet<File>(); 
Collection<Future<UncompressorResult>> futures = new LinkedList<Future<UncompressorResult>>(); 
Future<UncompressorResult> future = pool.submit(new Uncompressor(pool, compressedFile)); 
futures.add(future); 

while (!futures.isEmpty()) { 
    Future<UncompressorResult> future = futures.poll(); 
    UncompressorResult result = future.get(); 

    futures.addAll(result.getFutures()); 
    uncompressedFiles.addAll(result.getFiles()); 
} 

과를 : 자바 7 무엇을 할 것이라고되지 않은 모든 선물을 추적하기 위해 발신자를 변경, 결과는 선물과 파일의 튜플이되도록 Uncompressor을 변경하고있다,하지만 옵션이없는 압축 해제는 다음과 같이 변경됩니다.

public UncompressorResult call() throws Exception[ 
    List<File> uncompressedFiles = new ArrayList<File>(); 

    for (File entry : zipFiles) { 
     if (entry is not ZIP) { 
      uncompressedFiles.add(entry); 
     } else { 
      Callable<UncompressorResult> callable = new Uncompressor(this.pool, entry); 
      Future<UncompressorResult> f = pool.submit(callable); 
      futures.add(f); 
     } 
    } 

    return new UncompressorResult(uncompressedFiles, futures; 
} 
+0

찾을 수있는 문서에 따르면 ForkJoinTask는 Java 7의 일부입니까? 그 버전은 아직 사용하지 않고 있습니다. – Derek

+0

네, Java 7입니다. 옵션이 없기 때문에 zip 파일이 없을 때까지 호출자를 루프에 다시 작성할 수 있습니다. 내 대답을 편집 할게. – sharakan

+0

이런 식으로하는 것의 차이점은 무엇이며 선물을콜렉션으로 반환하는 것의 차이점은 무엇입니까? 근본적으로 빈 미래가있는 튜플과 파일 콜렉션을 만드는 것보다 쉽지 않을까요? 또한 코드를 사용하면 메서드 호출은 UncompressorResult 대신 Collection 이어야합니다. 맞습니까? 내 클래스는 Callable > – Derek