見出し画像

Androidでの7zの圧縮と解凍

1. Apatchのcommons compressライブラリ

Androidで7zの圧縮と解凍を行うには、Apacheのcommons compressライブラリを使います。多くのアーカイブ形式をサポートします。

ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200, bzip2, 7z, arj, lzma, snappy, DEFLATE and Z files.

2. プロジェクトの設定

「build.gradle(Module: app)」のdependenciesに以下を追加します。

    implementation 'org.apache.commons:commons-compress:1.8'
    implementation 'org.tukaani:xz:1.8'

3. コード

7zの圧縮と解凍を行うコードは次の通りです。
アセットに配置した「resouece1.txt」「resource2.txt」「resource3.txt」を内部ストレージにコピーした後、7zでの圧縮と解凍を行っています。

package net.npaka.sevenzex;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Window;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

//AppDelegate
public class AppDelegate extends Activity {

   //アプリ起動時に呼ばれる
   @Override
   public void onCreate(Bundle bundle) {
       super.onCreate(bundle);
       requestWindowFeature(Window.FEATURE_NO_TITLE);

       //7zの圧縮と解凍
       test7z();
   }

   //7zの圧縮と解凍
   private void test7z() {
       //アセットからストレージにファイルをコピー
       assets2storage("resource1.txt");
       assets2storage("resource2.txt");
       assets2storage("resource3.txt");
       String storage_dir = getFilesDir().getPath();
       ls(storage_dir);

       try {
           //7Zで圧縮
           File resource1 = new File(storage_dir+"/resource1.txt");
           File resource2 = new File(storage_dir+"/resource2.txt");
           File resource3 = new File(storage_dir+"/resource3.txt");
           SevenZ.compress(getFilesDir().getPath() + "/compress.7z", resource1, resource2, resource3);
           ls(storage_dir);

           //7Zで解凍
           SevenZ.decompress(storage_dir + "/compress.7z",
               new File(storage_dir + "/decompress"));
           ls(storage_dir+"/decompress");
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   //ストレージの一覧表示
   private void ls(String path) {
       String[] files = new File(path).list();
       String str = "ls["+path+"]>>>";
       for (int i = 0; i < files.length; i++) {
           str += files[i]+",";
       }
       android.util.Log.d("debug", str);

   }

   //アセットから内部ストレージにファイルをコピー
   private boolean assets2storage(String asset_file) {
       try {
           InputStream in = getAssets().open(asset_file);
           FileOutputStream out = openFileOutput(asset_file, Context.MODE_PRIVATE);
           byte[] buff = new byte[1024];
           int len = 0;
           while ((len = in.read(buff)) >= 0) {
               out.write(buff, 0, len);
           }
           out.close();
           in.close();
           return true;
       } catch (Exception e) {
           e.printStackTrace();
           return false;
       }
   }
}
package net.npaka.sevenzex;

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//7zのユーティリティ
public class SevenZ {
   //コンストラクタ
   private SevenZ() {
   }

   //圧縮
   public static void compress(String name, File... files) throws IOException {
       try (SevenZOutputFile out = new SevenZOutputFile(new File(name))){
           for (File file : files){
               addToArchiveCompression(out, file, ".");
           }
       }
   }

   //解凍
   public static void decompress(String in, File destination) throws IOException {
       SevenZFile sevenZFile = new SevenZFile(new File(in));
       SevenZArchiveEntry entry;
       while ((entry = sevenZFile.getNextEntry()) != null){
           if (entry.isDirectory()){
               continue;
           }
           File curfile = new File(destination, entry.getName());
           File parent = curfile.getParentFile();
           if (!parent.exists()) {
               parent.mkdirs();
           }
           FileOutputStream out = new FileOutputStream(curfile);
           byte[] content = new byte[(int) entry.getSize()];
           sevenZFile.read(content, 0, content.length);
           out.write(content);
           out.close();
       }
   }

   //圧縮アーカイブの追加
   private static void addToArchiveCompression(SevenZOutputFile out, File file, String dir) throws IOException {
       String name = dir + File.separator + file.getName();
       if (file.isFile()){
           SevenZArchiveEntry entry = out.createArchiveEntry(file, name);
           out.putArchiveEntry(entry);
           FileInputStream in = new FileInputStream(file);
           byte[] b = new byte[1024];
           int count = 0;
           while ((count = in.read(b)) > 0) {
               out.write(b, 0, count);
           }
           out.closeArchiveEntry();
       } else if (file.isDirectory()) {
           File[] children = file.listFiles();
           if (children != null){
               for (File child : children){
                   addToArchiveCompression(out, child, name);
               }
           }
       } else {
            android.util.Log.d("debug", file.getName() + " is not supported");
       }
   }
}


この記事が気に入ったらサポートをしてみませんか?