프로그래밍/안드로이드

안드로이드 - 압축 파일 사용하기

가카리 2015. 11. 5. 20:44
반응형

 

압축 파일 관리 기능은 자바에 의해 언어 차원에서 제공되므로 안드로이드도 별도의 추가 라이브러리 없이 압축 파일을 만들거나 해제할 수 있다.

 

ZipFile 클래스는 파일 기반의 zip 압축 파일을 다루며 압축 파일 내의 임의 파일을 랜덤으로 액세스한다.

 

다음 두가지 생성자가 있으며 File 객체로부터 생성할 수도 있고 압축 파일의 경로를 주어 열 수도 있다.

    

    ZipFile(File file [, int mode])

    ZipFile(String name)

 

File 객체로 생성할 때 mode에 OPEN_DELETE를 지정하면 사용 후 자동으로 삭제되므로 임시적으로 압축 파일을 만들어 할용할 수 있다.

 

    Enumeration<? extends ZipEntry> entries()

    ZipEntry getEntry(String entryName)

    int size()

    InputStream getInputStream(ZipEntry entry)

 

entries메소드는 압축 파일에 들어간 순서대로 모든 파일과 디렉터리의 목록을 구하며 getEntry 메소드는 지정한 경로의 항목을 구한다.

size는 압축 파일에 포함된 항목의 총 개수를 구한다. getInputStream은 항목을 액세스할 수 있는 스트림을 구하며 이 스트림에서 데이터를 읽음으로써 압축을 푼 데이터를 추출한다.

 

압축파일에 포함된 항목 하나는 ZipEntry클래스로 표현한다. 관련 메소드는 다음과 같다.

 

메소드

설명

String getName()

파일의 이름

long getSize()

압축을 풀었을 때의 원래 크기

long getCompressedSize()

압축된 크기

long getCrc()

체크섬

long getTime()

최후 수정된 시간

boolean isDirectory()

디렉터리인지 조사한다.

 

다음 동그라미 친 부분을 유의하자 assets에 ZipTest.zip 파일 추가해야 예제가 잘 된다.

ZipTest.zip 다운하기

ZipTest.zip

 

 

이번 예제는 SD카드의 정보를 사용하므로 매니페스트 파일에 퍼미션을 추가해야한다.

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.ch25_readzip"

android:versionCode="1"

android:versionName="1.0" >

 

<uses-sdk

android:minSdkVersion="19"

android:targetSdkVersion="19" />

 

<application

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<activity

android:name=".ReadZip"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

 

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

 

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

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

 

</manifest>

 

readzip.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent"

>

 

<Button

android:id="@+id/btnlist"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="list"

/>

<Button

android:id="@+id/btna"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="a.txt"

/>

<Button

android:id="@+id/btnb"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="b.txt"

/>

    <TextView

     android:id="@+id/result"

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:text="result"

     />

 

</LinearLayout>

 

ReadZip.java

package com.example.ch25_readzip;

 

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Enumeration;

import java.util.zip.ZipEntry;

import java.util.zip.ZipFile;

import java.util.zip.ZipInputStream;

 

import android.app.Activity;

import android.content.Context;

import android.content.res.AssetManager;

import android.os.Bundle;

import android.os.Environment;

import android.view.View;

import android.widget.TextView;

 

public class ReadZip extends Activity {

    TextView mResult;

    String mPath;

    

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.readzip);

      

        mPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ZipTest.zip";

        mResult = (TextView)findViewById(R.id.result);

        

        //에셋의 zip 파일 복사하기

        CopyAsset(this, "ZipTest.zip", "ZipTest.zip");

    }

 

    public void mOnClick(View v){

        switch(v.getId()){

        case R.id.btnlist:

            ShowList();

            break;

        case R.id.btna:

            ShowA();

            break;

        case R.id.btnb:

            ShowB();

            break;

        }

    }

    

    //Zip파일을 읽은 다음 정보를 보여주는 메소드

    void ShowList(){

        try{

            ZipFile zip = new ZipFile(mPath);

            String s = "";

            s = "size = " + zip.size() + "\n";

            ZipEntry e;

            

            Enumeration<? extends ZipEntry> ent = zip.entries();//zip파일의 엔트리를 가져옴

            while(ent.hasMoreElements()){//엔트리가 있으면

                e = (ZipEntry)ent.nextElement();//가져옴

                s = s + "name = " + e.getName() + " , size = " + e.getSize() +

                        " , Compsize = " + e.getCompressedSize() + "\n";

            }

            

            mResult.setText(s);

        }catch(Exception e){

            return;

        }

    }

    

    void ShowA(){

        try{

            ZipFile zip;

            zip = new ZipFile(mPath);

            

            //a.txt 읽기 위해

            InputStream is = zip.getInputStream(zip.getEntry("a.txt"));

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];

            

            int len;

            //내용을 출력하는 부분

            for(;;){

                len = is.read(buffer);

                if(len <= 0)break;

                baos.write(buffer, 0, len);

            }

            is.close();

            mResult.setText(baos.toString());

        }catch(IOException e){

            

        }

    }

 

    void ShowB(){

        try{

            ZipInputStream zin = new ZipInputStream(new FileInputStream(mPath));

            for(;;){

                ZipEntry ze = zin.getNextEntry();//다음폴더를 들어가기위해

                if(ze == null) break;

                if(ze.getName().equals("subdir/b.txt")){//찾으면?

                    //아래부분은 출력을 하는부분

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    byte[] buffer = new byte[1024];

                    

                    int len;

                    for(;;){

                        len = zin.read(buffer);

                        if(len <= 0) break;

                        baos.write(buffer, 0, len);

                    }

                    mResult.setText(baos.toString());

                    break;

                }

            }

            zin.close();

        }catch(Exception e){

            

        }

    }    

    

    //Zip파일을 sd카드에 복사하는 메소드

    public boolean CopyAsset(Context context, String src, String dest){

        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

            return false;

        }

        

        String root = Environment.getExternalStorageDirectory().getAbsolutePath();

        

        String destpath = root + "/" + dest;

        File f = new File(destpath);

        if(f.exists()){

            return true;

        }

        

        AssetManager am = context.getAssets();

        //파일을 실제로 복사하는 부분

        try{

            InputStream is = am.open(src);

            FileOutputStream os = new FileOutputStream(destpath);

            byte buffer[] = new byte[1024];

            for(;;){

                int read = is.read(buffer);

                if(read <= 0) break;//파일 읽음

                os.write(buffer, 0, read);

            }

            is.close();

            os.close();

        

        }catch(IOException e){

            return false;

        }

 

        

        return true;

    }

    

}

 

 

출력 화면

 

 

a.txt 버튼을 눌렀을 때

 

b.txt 버튼을 눌렀을 때