2017-01-09 98 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 

但是,當你打開創建壓縮文件有兩個目錄裏:

Ä? 
ą 

第一個是空的,文本文件應該在'±'目錄中。

回答

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字符,使用不同的庫看起來是唯一的解決方案。

相關問題