2 votes

Apache Commons ZipArchiveOutputStream se casse lors de l'ajout de noms de fichiers avec des caractères non ASCII.

J'utilise un flux de données org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream pour ajouter des fichiers provenant d'un dépôt Subversion. Cela fonctionne bien tant que je n'utilise pas les trémas allemands (ä, ö, ü) ou tout autre caractère spécial dans le nom du fichier. Je me demande quel serait le moyen le plus rapide de lui faire accepter des caractères non ASCII ?

def zip(repo: SVNRepository, out: OutputStream, url: String, resourceList: Seq  
       [SVNResource]) {
  val zout = new ZipArchiveOutputStream(new BufferedOutputStream(out))
  zout.setEncoding("Cp437");
  zout.setFallbackToUTF8(true);
  zout.setUseLanguageEncodingFlag(true);
  zout.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE);
  try {
    for (resource <- resourceList) {
      addFileToStream(repo, zout, resource)
    }
  }
  finally {
    zout.finish
    zout.close
  }
}

private def addFileToStream(repo: SVNRepository, zout: ZipArchiveOutputStream, resource:SVNResource): ZipArchiveOutputStream = {
  val entry = resource.entry
  val url = YSTRepo.getAbsolutePath(entry)
  if (FILE == entry.getKind.toString) {
    val file = new File(url)
    val zipEntry = new ZipArchiveEntry(file, url)   
    zout.putArchiveEntry(zipEntry)
    val baos = new ByteArrayOutputStream()
    val fileprops = new SVNProperties()
    repo.getFile(url, -1, fileprops, baos)
    IOUtils.copy(new ByteArrayInputStream(baos.toByteArray), zout)
    zout.closeArchiveEntry
  } else if (DIR == entry.getKind.toString) {
    if (resource.hasChildren) {
      val dirProps = new SVNProperties()
      val entries = repo.getDir(url, -1, dirProps, new java.util.ArrayList[SVNDirEntry])
      for (child <- SVNResource.listDir(repo, entries.toList.asInstanceOf[Seq SVNDirEntry]])) {
        addFileToStream(repo, zout, child)
      }
    }
  }
  zout
}

3voto

trajectory Points 1399

J'ai résolu le problème en mettant

UnicodeExtraFieldPolicy.NOT_ENCODEABLE 

à

UnicodeExtraFieldPolicy.ALWAYS

Les noms de fichiers s'affichent désormais correctement avec Linux-Unzip, Windows-Compressed-Folders, IZArc et WINZIP.

2voto

Anon Points 1946

D'après vos commentaires, il semble que le vrai problème soit avec le système Linux. unzip et/ou l'encodage pris en charge par votre système de fichiers Linux. Une solution consiste à passer l'option -U pour unzip, ce qui permet d'échapper à tout caractère Unicode dans les noms de fichiers.

Cela dit, je recommande également de supprimer les lignes suivantes lorsque vous écrivez votre fichier ZIP :

zout.setEncoding("Cp437");
zout.setFallbackToUTF8(true);
zout.setUseLanguageEncodingFlag(true);

Et remplacez-les par ce qui suit :

zout.setEncoding("UTF-8");

Cela devrait permettre d'obtenir la meilleure portabilité possible.

0voto

Kevin Wright Points 31665

Vous pouvez essayer de faire passer le nom du fichier par URLEncoder d'abord : http://download.oracle.com/javase/6/docs/api/java/net/URLEncoder.html

Cela garantira que le nom du fichier zippé est un pur ASCII.

Lors de la relecture, utilisez URLDecoder pour récupérer le jeu de caractères UFT-8 complet : http://download.oracle.com/javase/6/docs/api/java/net/URLDecoder.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X