2012-03-30 4 views
21

ZipFile 클래스를 통해 큰 zip 파일 (250MB)을 열어 항목을 읽으려고 시도합니다. 이것은 에뮬레이터와 실제 하드웨어에서 2.x에서 잘 작동합니다. 내 타블렛 (Asus Transformer 4.0.3 실행) 또는 에뮬레이터 (3.2)에서 정확한 코드를 사용하면 항목을 읽을 수 없습니다. ZipFile 클래스의 size() 함수는 항상 0을 반환하고 ZipFile은 모든 우편 항목을 반환하지 않습니다. 태블릿에서 ROM과 함께 제공되는 우편 앱조차도 항목을 읽을 수 없습니다. zip 파일이 손상되지 않았습니다. 나는 그것을 검사했다.Android 3.x + Java ZipFile 클래스 - 큰 파일에서 ZipEntries를 읽을 수 없습니다.

ZipFile에서 읽는 코드는 더 작은 zip 파일이있는 모든 버전에서 정상적으로 작동합니다. 2.x와 3.x/4.x 사이에서 변경된 사항은 무엇입니까?

내 테스트 파일은 HighVoltage Sid Collection의 C64Music.zip입니다. 그것은 40,000 이상의 파일을 포함하며 약 250MB입니다.

나는 어디를보아야하는지 모른다.

+0

3.x/4.x를 실행중인 Asus 또는 에뮬레이터에서 다른 zip 파일을 읽으려고 했습니까? 이 zip 파일에만 문제가 있습니까? –

+0

예외를 삼키고 있습니까? 그렇지 않으면 getName()은 zip 파일의 이름을 반환합니까? (간단한 테스트지만, 놀라운 것을 보여줄 수도 있습니다.) OPEN_READ 플래그를 사용하거나 사용하지 않고 zip을 열면 다른 결과가 나타 납니까? –

+0

'JarFile'로 시도해 볼 수 있을지 모르겠다. ... –

답변

0
public class Compress { 

    private static final int BUFFER = 2048; 
    private String[] _files; 
    private String _zipFile; 
    public Compress(String[] files, String zipFile) { 
    _files = files; 
    _zipFile = zipFile; 
    } 
    public void zip() { 
    try { 
     BufferedInputStream origin = null; 
     FileOutputStream dest = new FileOutputStream(_zipFile); 
     ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); 
     byte data[] = new byte[BUFFER]; 
     for(int i=0; i < _files.length; i++) { 
     Log.v("Compress", "Adding: " + _files[i]); 
     FileInputStream fi = new FileInputStream(_files[i]); 
     origin = new BufferedInputStream(fi, BUFFER); 
     ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1)); 
     out.putNextEntry(entry); 
     int count; 
     while ((count = origin.read(data, 0, BUFFER)) != -1) { 
      out.write(data, 0, count); 
     } 
     origin.close(); 
     } 

     out.close(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 

    } 

} 

Call Compress like given below where you want to zip a file :---- 

String zipFilePath = "fileName.zip"; 
File zipFile = new File(zipFilePath); 
String[] files = new String[] {"/sdcard/fileName"}; 
if(!zipFile.exists()){ 
    new Compress(files, zipFilePath).zip(); 
    } 
0

UI 스레드에 대한 악용을 막기 위해 3.x/4.x에서 많은 변경이있었습니다. 따라서 고비용의 디스크 I/O 작업을 별도의 Thread으로 오프 로딩하지 않기 때문에 앱이 중단 될 수 있습니다.

2

이 안드로이드 ZipFile를 구현 알려진 문제입니다 :

http://code.google.com/p/android/issues/detail?id=23207

는 기본적으로 파일은 65K 항목을 지원 우편 번호. 더 많은 수의 항목을 지원하는 Zip64라는 zip 파일 형식의 확장 버전이 있습니다. 불행히도 안드로이드의 ZipFile은 Zip64를 읽을 수 없습니다. 아마도 C64Music.zip 파일은 Zip64 형식입니다.

해결 방법은 원시 구현 대신 Apache Commons Compress 라이브러리를 사용하는 것입니다. 그들의 ZipFile 버전은 Zip64를 지원합니다 : http://commons.apache.org/compress/apidocs/org/apache/commons/compress/archivers/zip/ZipFile.html