4

当社の製品にはZipOutputStream、ディレクトリを圧縮するために使用するエクスポート機能があります。ただし、中国語または日本語の文字を含むファイル名を含むディレクトリを圧縮しようとすると、エクスポートが正しく機能しません。何らかの理由で、zipファイル内の新しいファイルの名前が異なります。これが私たちのzipコードの例です:

ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
out.setEncoding("UTF-8");
//program to add directory to zip 
//program add/create file to zip
out.close();

同じくJavaで構築された私のインポートアルゴリズムは、ファイル/ディレクトリ名に中国語/日本語の文字が含まれている場合でも、zipファイルを正しくインポートできます。

 Zipfile zipfile = new ZipFile(zipPath, "UTF-8");
 Enumeration e = zipFile.getEntries();
 while (e.hasMoreElements()) {
 entry = (ZipEntry) e.nextElement();
 String name = entry.getName();
         ....

zipソフトウェアのプログラムでUTF-8エンコードされたファイルを解凍するのに問題がありますか、それともutf-8エンコードを使用して既存のソフトウェアで簡単に使用できるzipファイルを作成するために特別な何かが必要ですか?


私はサンプルプログラムを書きました:

package ZipFile;

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

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

public class ZipFolder{
public static void main(String[] a) throws Exception
{
String srcFolder = "D:/9.4_work/openscript_repo/中文124.All/中文";
String destZipFile = "D:/Eclipse_Projects/OpenScriptDebuggingProject/src/ZipFile/demo.zip";
zipFolder(srcFolder, destZipFile);
}

static public void zipFolder(String srcFolder, String destZipFile) throws Exception
{
    ZipOutputStream zip = null;
    FileOutputStream fileWriter = null;

    fileWriter = new FileOutputStream(destZipFile);
    zip = new ZipOutputStream(fileWriter);
    zip.setEncoding("UTF-8");
    // using GBK encoding, the chinese name can be correctly displayed when unzip
    // zip.setEncoding("GBK");

    addFolderToZip("", srcFolder, zip);
    zip.flush();
    zip.close();
}

static private void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws Exception
{

    File folder = new File(srcFile);
    if (folder.isDirectory()) {
        addFolderToZip(path, srcFile, zip);
    }
    else {
        byte[] buf = new byte[1024];
        int len;
        FileInputStream in = new FileInputStream(srcFile);
        zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
        while ((len = in.read(buf)) > 0) {
            zip.write(buf, 0, len);
        }
    }
}

static private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception
{
    File folder = new File(srcFolder);

    for (String fileName : folder.list()) {
        if (path.equals("")) {
            addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
        }
        else {
            addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
        }
    }
}

}

4

2 に答える 2

1

次のユーティリティクラスを使用すると、GZIP圧縮アルゴリズムを使用して文字列を圧縮および解凍できます。これは、たとえばデータベースに長い文字列を保存する場合に役立ちます。

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;


public class GzipStringUtil {


    public static byte[] compressString(String uncompressedString) throws IllegalArgumentException, IllegalStateException {
        if (uncompressedString == null) {
            throw new IllegalArgumentException("The uncompressed string specified was null.");
        }
        try {
            byte[] utfEncodedBytes = uncompressedString.getBytes("UTF-8");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos);
            gzipOutputStream.write(utfEncodedBytes);
            gzipOutputStream.finish();
            gzipOutputStream.close();
            return baos.toByteArray();
        }
        catch (Exception e) {
            throw new IllegalStateException("GZIP compression failed: " + e, e);
        }
    }


    public static String uncompressString(byte[] compressedString) throws IllegalArgumentException, IllegalStateException {
        if (compressedString == null) {
            throw new IllegalArgumentException("The compressed string specified was null.");
        }
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(compressedString);
            GZIPInputStream gzipInputStream = new GZIPInputStream(bais);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            for (int value = 0; value != -1;) {
                value = gzipInputStream.read();
                if (value != -1) {
                    baos.write(value);
                }
            }
            gzipInputStream.close();
            baos.close();
            return new String(baos.toByteArray(), "UTF-8");
        }
        catch (Exception e) {
            throw new IllegalStateException("GZIP uncompression failed: " + e, e);
        }
    }
}

上記のクラスの使用例を提供するTestCaseは次のとおりです。

public class GzipStringUtilTest extends TestCase {

    public void testGzipStringUtil() {
        String input = "This is a test. This is a test. This is a test. This is a test. This is a test.";
        System.out.println("Input:        [" + input + "]");
        byte[] compressed = GzipStringUtil.compressString(input);
        System.out.println("Compressed:   " + Arrays.toString(compressed));
        System.out.println("-> Compressed input string of length " + input.length() + " to " + compressed.length + " bytes");
        String uncompressed = GzipStringUtil.uncompressString(compressed);
        System.out.println("Uncompressed: [" + uncompressed + "]");
        assertEquals("The uncompressed string [" + uncompressed + "] unexpectedly does not match the input string [" + input + "]", input, uncompressed);
        System.out.println("The input was compressed and uncompressed successfully, and the input matches uncompressed output.");
    }
}
于 2012-08-09T11:02:58.323 に答える
1

ここでの一番の答えはあなたの質問に答えるかもしれません。残念ながら、Zip形式では、どのコンピュータでもファイル名を正しく表示するZipファイルを作成できないことが示唆されているようです。

https://superuser.com/questions/60379/linux-zip-tgz-filenames-encoding-problem

エンコーディングをGBKに設定すると機能することを期待しています。これは、システムのデフォルトのエンコーディングであり、7zipが開くすべてのzipファイルにそれを使用しているためです。

これはrar7zフォーマットのサポートが優れていることを示しています。

特にJavaを使用したzip形式のUTF-8に関するブログエントリを見つけました。これは、現在のバージョンのJavaでは作成されていない可能性のある新しいバージョンのZIP仕様があることを示していますが、Java7では作成されます。Apacheクラスもこれを使用しているかどうかはわかりません。

http://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in

于 2011-06-07T09:50:40.983 に答える