2017-01-09 23 views
1

いくつかのディレクトリを内部に持つzipアーカイブを作成しようとしています。いくつかのディレクトリには、±、ę、łなどのポーランド語の文字があります。名前に特殊文字があるディレクトリの場合は、zipファイルに別のディレクトリが作成されます。次のコードで間違っているもの:特殊文字を含むディレクトリでzipを作成する

import java.io.File; 
import java.io.IOException; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.nio.file.*; 
import java.nio.file.attribute.BasicFileAttributes; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.Map; 

public class Main { 

    public static void main(String[] args) throws URISyntaxException, IOException { 
    Map<String, String> env = new HashMap<>(); 
    env.put("create", "true"); 
    URI fileUri = new File("zipfs.zip").toPath().toUri(); 
    URI zipUri = new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null); 

    try (FileSystem zipfs = FileSystems.newFileSystem(zipUri, env)) { 

     Path directory = zipfs.getPath("ą"); 
     Files.createDirectory(directory); 
     Path pathInZipfile = directory.resolve("someFile.txt"); 
     Path source = Paths.get("source.txt"); 

     Files.copy(source, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); 
    } 

    FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.emptyMap()); 

    Path root = zipFs.getPath("/"); 

    Files.walkFileTree(root, new SimpleFileVisitor<Path>() { 
     @Override 
     public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { 
      System.out.println(path); 
      return FileVisitResult.CONTINUE; 
     } 

     @Override 
     public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 
      System.out.println(dir); 
      return super.preVisitDirectory(dir, attrs); 
     } 
    }); 
    } 
} 

このプログラムの出力は予想通りである:

/ 
/ą/ 
/ą/someFile.txt 

をしかし、あなたが作成したzipファイルを開いたときに、2つのディレクトリがあります内側:

Ä? 
ą 

最初は空で、テキストファイルは '±'ディレクトリにあるはずです。

答えて

1

ZipFileSystemは、フォルダで言語エンコードフラグ(EFS)を設定していないようです。このフラグは、基本的に「このパスはUTF-8を使用しています。

はのは(面白くない行をスキップ)zipdetailsを見てみましょう:

0072 CENTRAL HEADER #1  02014B50 
007A General Purpose Flag 0000      // <= no EFS flag 
00A0 Filename    'ą/' 

00AC CENTRAL HEADER #2  02014B50 
00B4 General Purpose Flag 0800 
    [Bits 1-2]   0 'Normal Compression' 
    [Bit 11]    1 'Language Encoding'  // <= EFS flag 
00DA Filename    'ą/someFile.txt' 

そうでない場合は、ą/が正しくUTF-8でエンコードされます。

このフラグがないと、エンコードを選択するためにzipファイルを読み込んだり解凍したりすることになります(通常はシステムのデフォルトです)。 unzipがここにも動作しません:

$ unzip -t zipfs.zip 
Archive: zipfs.zip 
    testing: -à/      OK 
    testing: ą/someFile.txt   OK 
No errors detected in compressed data of zipfs.zip. 

注意を、あなたは-UUとUnicodeのサポートを無効にした場合、あなたは両方のエントリでを取得します。

7zはここに良い作品(私のシステムのデフォルトのエンコーディングはUTF-8であるという理由だけで):

$ 7z l zipfs.zip 
... 
    Date  Time Attr   Size Compressed Name 
------------------- ----- ------------ ------------ ------------------------ 
2017-01-10 22:51:14 D....   0   0 ą 
2017-01-10 22:51:15 .....   0   2 ą/someFile.txt 
------------------- ----- ------------ ------------ ------------------------ 
2017-01-10 22:51:15     0   2 1 files, 1 folders 

zipファイルが送られている場合は、(zipファイルが開かれた道を強制することができない場合ユーザーがサーバーの代わりにユーザー)を使用するか、フォルダー内のASCII文字のみを使用して、別のライブラリーを使用することが唯一の解決策のように見えます。

関連する問題