Проблемы на Mac с java.util.zip. * (Извлечение) - PullRequest
2 голосов
/ 15 марта 2011

Я создал программу и создал функцию экспорта для документов (записей). Процедура: Пользователь добавил избранные документы. Существует 2-3 стратегии (BibTex, RIS, HTML) пользователь может выбрать для экспорта своих документов. Для каждой стратегии создается новый файл .zip со всеми документами внутри. Созданные .zip архивы отправляются пользователю по электронной почте.

Для меня (Windows) это прекрасно работает. Я могу извлечь эти архивы без проблем. Но мой друг, использующий Mac, получает ошибки при их извлечении, и я не знаю, почему.

Здесь важный код:

for ( String strategy : strategies ) {
// Coderedundanz
// Jede Strategie benötigt eigene Parameter
if (strategy.equals("BibTex")) {
    _zipName = "ezdl_export_bibtex";
    _fileExtension = ".bib";
    _strategy = csf.bibTex;
}
else if (strategy.equals("RIS")) {
    _zipName = "ezdl_export_ris";
    _fileExtension = ".ris";
    _strategy = csf.ris;
}
else if (strategy.equals("HTML")) {
    _zipName = "ezdl_export_html";
    _fileExtension = ".html";
    _strategy = csf.html;
}
else {
    _zipName = _zipExtension = "";
    _fileExtension = "";
    _strategy = null;
}

// Gibt es eine korrekte Strategie?
if ( !_zipName.equals("") && !_fileExtension.equals("") && _strategy != null) {
    // 1. .zip Datei generieren
    // 2. Für jedes TextDocument eine eigene Datei erstellen
    // 3. Datei in die .zip Datei einfügen
    // 4. .zip Datei schließen und in die E-Mail hinzufügen
    File file = File.createTempFile(_zipName + _zipExtension, ".tmp");
    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
    out.setLevel(6);
    for ( TextDocument document : documents ) {
        out.putNextEntry(new ZipEntry( document.getOid() + _fileExtension));

        String temp = _strategy.print ( (TextDocument) document).asString().toString();

        out.write( temp.getBytes() );
        out.closeEntry();
    }

    out.finish();
    out.close();

    PreencodedMimeBodyPart part_x = new PreencodedMimeBodyPart("base64");
    part_x.setFileName(_zipName + _zipExtension);
    part_x.setContent(new String(Base64Coder.encode( getBytesFromFile (file))), "text/plain");
    multi.addBodyPart(part_x);

    if (file.exists())
        file.delete();

Вы видите, что для каждой стратегии создается собственный архив. Программа просматривает документы (TextDocument) и с _strategy.print вы получаете строку в качестве вывода.

Как я сказал .. для меня это прекрасно работает, но не на Mac. Есть ли различия? Я думаю ... ZIP - это ZIP. Или я должен создать тарболы (.tar.gz) для Mac?

EDIT:

serena:tmp3 alex$ unzip ezdl_export_bibtex.zip 
Archive:  ezdl_export_bibtex.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
note:  ezdl_export_bibtex.zip may be a plain executable, not an archive
unzip:  cannot find zipfile directory in one of ezdl_export_bibtex.zip or
        ezdl_export_bibtex.zip.zip, and cannot find 

Вот экран: http://img3.imageshack.us/i/ziperror.png. Показывает ошибку: «Невозможно разархивировать - Ошибка - 1 - Операция не разрешена»

Я также изменил свой код на:

out.write( temp.getBytes() );
out.flush();
out.closeEntry();

Но все та же проблема.

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Хотя это не решает вашу проблему напрямую, вы можете проверить целостность файла zip, используя параметр -t в командной строке.

$ unzip -t java-puzzlers.zip | tail -1
No errors detected in compressed data of java-puzzlers.zip.

Кроме того, вы можете проверять разрешения родительского каталога, проходя по пути, пока не увидите проблему.

$ ls -ld ..
drwxr-xr-x@ 26 trashgod  staff  884 Jan 17  2010 ..
$ ls -ld ../..
drwx------+ 23 trashgod  staff  782 Dec 17 17:15 ../..

Приложение: Если это "имеет отношение к кодированию", я всегда начинаю с часто встречающегося у Джоэла Спольскицитируемая статья на эту тему.Этот ответ также может быть полезен.

1 голос
/ 15 марта 2011

Попробуйте вызвать flush() в потоке вывода до вызова closeEntry().

...