web-dev-qa-db-ja.com

android=

ユーザーがメールでプロジェクトを共有できるようにするには、「プロジェクト」フォルダを圧縮する必要があります。複数のファイルを1つのZipに圧縮するクラスを見つけましたが、フォルダー構造をZipに保持する必要があります。 Androidでこれを達成する方法はありますか?前もって感謝します。

22
Mark

このコードでうまくいくはずです。

注:WRITE_EXTERNAL_STORAGE権限をmanifest.xmlファイルに追加して、ファイル書き込み権限をアプリに追加する必要があります。

/*
 * 
 * Zips a file at a location and places the resulting Zip file at the toLocation
 * Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.Zip");
 */

public boolean zipFileAtPath(String sourcePath, String toLocation) {
    final int BUFFER = 2048;

    File sourceFile = new File(sourcePath);
    try {
        BufferedInputStream Origin = null;
        FileOutputStream dest = new FileOutputStream(toLocation);
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
                dest));
        if (sourceFile.isDirectory()) {
            zipSubFolder(out, sourceFile, sourceFile.getParent().length());
        } else {
            byte data[] = new byte[BUFFER];
            FileInputStream fi = new FileInputStream(sourcePath);
            Origin = new BufferedInputStream(fi, BUFFER);
            ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
            entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping
            out.putNextEntry(entry);
            int count;
            while ((count = Origin.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
        }
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

/*
 * 
 * Zips a subfolder
 * 
 */

private void zipSubFolder(ZipOutputStream out, File folder,
        int basePathLength) throws IOException {

    final int BUFFER = 2048;

    File[] fileList = folder.listFiles();
    BufferedInputStream Origin = null;
    for (File file : fileList) {
        if (file.isDirectory()) {
            zipSubFolder(out, file, basePathLength);
        } else {
            byte data[] = new byte[BUFFER];
            String unmodifiedFilePath = file.getPath();
            String relativePath = unmodifiedFilePath
                    .substring(basePathLength);
            FileInputStream fi = new FileInputStream(unmodifiedFilePath);
            Origin = new BufferedInputStream(fi, BUFFER);
            ZipEntry entry = new ZipEntry(relativePath);
            entry.setTime(file.lastModified()); // to keep modification time after unzipping
            out.putNextEntry(entry);
            int count;
            while ((count = Origin.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            Origin.close();
        }
    }
}

/*
 * gets the last path component
 * 
 * Example: getLastPathComponent("downloads/example/fileToZip");
 * Result: "fileToZip"
 */
public String getLastPathComponent(String filePath) {
    String[] segments = filePath.split("/");
    if (segments.length == 0)
        return "";
    String lastPathComponent = segments[segments.length - 1];
    return lastPathComponent;
}
46
HailZeon

これが私のやり方です:

private static void zipFolder(String inputFolderPath, String outZipPath) {
    try {
        FileOutputStream fos = new FileOutputStream(outZipPath);
        ZipOutputStream zos = new ZipOutputStream(fos);
        File srcFile = new File(inputFolderPath);
        File[] files = srcFile.listFiles();
        Log.d("", "Zip directory: " + srcFile.getName());
        for (int i = 0; i < files.length; i++) {
            Log.d("", "Adding file: " + files[i].getName());
            byte[] buffer = new byte[1024];
            FileInputStream fis = new FileInputStream(files[i]);
            zos.putNextEntry(new ZipEntry(files[i].getName()));
            int length;
            while ((length = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, length);
            }
            zos.closeEntry();
            fis.close();
        }
        zos.close();
    } catch (IOException ioe) {
        Log.e("", ioe.getMessage());
    }
}
18
SpyZip

Java.util.Zipオブジェクトを使用する場合は、ディレクトリ構造を変更しないスクリプトを記述できます。

1
Charles

HailZeonのコードを作り直して、Windowsで正しく動作するようにしました。新しいエントリを開始する前にZipエントリを閉じる必要があり、「/ file.txt」のようなエントリ名で「/」を開始すると問題が発生します

/**
 * Zips a Folder to "[Folder].Zip"
 * @param toZipFolder Folder to be zipped
 * @return the resulting ZipFile
 */
public static File zipFolder(File toZipFolder) {
    File ZipFile = new File(toZipFolder.getParent(), format("%s.Zip", toZipFolder.getName()));
    try {
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(ZipFile));
        zipSubFolder(out, toZipFolder, toZipFolder.getPath().length());
        out.close();
        return ZipFile;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

/**
 * Main Zip Function
 * @param out Target ZipStream
 * @param folder Folder to be zipped
 * @param basePathLength Length of original Folder Path (for recursion)
 */
private static void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException {

    final int BUFFER = 2048;

    File[] fileList = folder.listFiles();
    BufferedInputStream Origin = null;
    for (File file : fileList) {
        if (file.isDirectory()) {
            zipSubFolder(out, file, basePathLength);
        } else {
            byte data[] = new byte[BUFFER];

            String unmodifiedFilePath = file.getPath();
            String relativePath = unmodifiedFilePath.substring(basePathLength + 1);

            FileInputStream fi = new FileInputStream(unmodifiedFilePath);
            Origin = new BufferedInputStream(fi, BUFFER);

            ZipEntry entry = new ZipEntry(relativePath);
            entry.setTime(file.lastModified()); // to keep modification time after unzipping
            out.putNextEntry(entry);

            int count;
            while ((count = Origin.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            Origin.close();
            out.closeEntry();
        }
    }
}
1
save_jeff

この location からZip4jライブラリを使用します。 jarファイルを"app/libs/"フォルダーにインポートします。次のコードを使用して、ディレクトリ/ファイルを圧縮します...

try {
    File input = new File("path/to/your/input/fileOrFolder");
    String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zippedItem.Zip";
    ZipParameters parameters = new ZipParameters();
    parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
    parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
    File output = new File(destinationPath);
    ZipFile zipFile = new ZipFile(output);
    // .addFolder or .addFile depending on your input
    if (sourceFile.isDirectory())
        zipFile.addFolder(input, parameters);
    else
        zipFile.addFile(input, parameters);
    // Your input file/directory has been zipped at this point and you
    // can access it as a normal file using the following line of code
    File zippedFile = zipFile.getFile();
} catch (ZipException e) {
    Log.e(TAG, Log.getStackTraceString(e));
}
0
Sammie
public static boolean Zip(File sourceFile, File zipFile) {
    List<File> fileList = getSubFiles(sourceFile, true);
    ZipOutputStream zipOutputStream = null;
    try {
        zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));
        int bufferSize = 1024;
        byte[] buf = new byte[bufferSize];
        ZipEntry zipEntry;
        for(int i = 0; i < fileList.size(); i++) {
            File file = fileList.get(i);
            zipEntry = new ZipEntry(sourceFile.toURI().relativize(file.toURI()).getPath());
            zipOutputStream.putNextEntry(zipEntry);
            if (!file.isDirectory()) {
                InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
                int readLength;
                while ((readLength = inputStream.read(buf, 0, bufferSize)) != -1) {
                    zipOutputStream.write(buf, 0, readLength);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        IoUtils.closeOS(zipOutputStream);
    }
    return true;
}    

public static List<File> getSubFiles(File baseDir, boolean isContainFolder) {
    List<File> fileList = new ArrayList<>();
    File[] tmpList = baseDir.listFiles();
    for (File file : tmpList) {
        if (file.isFile()) {
            fileList.add(file);
        }
        if (file.isDirectory()) {
            if (isContainFolder) {
                fileList.add(file); //key code
            }
            fileList.addAll(getSubFiles(file));
        }
    }
    return fileList;
}
0
Fang