Проблемы на Mac с java.util.zip.* (извлечение)

Я сделал программу и создал функцию экспорта документов (записей). Процедура: у пользователя есть избранные документы. Существует 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?

ИЗМЕНИТЬ:

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();

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


person Ioannis K.    schedule 15.03.2011    source источник
comment
О каких ошибках вы говорите? (Пожалуйста, добавьте их к своему вопросу с трассировкой стека, если это возможно.)   -  person Jeremy    schedule 15.03.2011
comment
... и если 'flush()' не работает, попробуйте опубликовать SSCCE (pscode.org/sscce.html), желательно с комментариями на английском языке. ;)   -  person Andrew Thompson    schedule 15.03.2011
comment
О верно. Я не видел своих комментариев на немецком :-) Это просто заметки для меня.. но.. я думаю, что эти заметки действительно устарели.   -  person Ioannis K.    schedule 15.03.2011
comment
Переформатированный код; пожалуйста, верните, если неправильно.   -  person trashgod    schedule 17.03.2011
comment
Похоже, у вас есть две потенциальные точки отказа: часть zip и часть MIME. Можно ли изолировать их друг от друга?   -  person Michael Brewer-Davis    schedule 17.03.2011
comment
Правильно. Я изменил тип MIME с text/plain на application/zip. Но я думаю, что это не имеет никакого эффекта.   -  person Ioannis K.    schedule 19.03.2011


Ответы (2)


Хотя это не решает вашу проблему напрямую, вы можете проверить целостность файла 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 ../..

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

person trashgod    schedule 17.03.2011
comment
Эй, мусорный бог. После нескольких тестов я получил свою проблему, но не нашел решения. Это как-то связано с кодировкой файлов. Я попытался закодировать свою строку (содержимое файлов в zip) в UTF-8 (URLEncoder.encode (строка, UTF-8)). И вуаля! У MAC нет проблем с открытием .zip-архива.. поэтому ошибок не возникает. Это работает, но мои файлы бесполезны, потому что все закодировано в UTF-8. Поэтому мне нужен тип кодирования, который принимается во всех системах. Я попробовал ISO-8859-1, но получил ту же ошибку на MAC. Как я могу решить свою проблему сейчас? - person Ioannis K.; 19.03.2011
comment
Если unzip -t не сообщает об ошибках, я предполагаю, что ваша стратегия по умолчанию использует кодировку Windows. . Что производит System.getProperty("file.encoding")? Чем UTF-8 бесполезен? - person trashgod; 19.03.2011
comment
Я запускаю Tomcat 7 на сервере Linux. System.getProperty(file.encoding) возвращает ANSI_X3.4-1968 UTF-8 бесполезен, потому что, когда я открываю файлы, я вижу только такие вещи, как 2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fsummary%3Fdoi%3D10.1.1. 12.1933%3C%2Fa%3E%3C%2Fli%3E%3C%2Ful%3E%3Cbr... Это не совсем читаемо... Поэтому мне нужен тип кодировки для всех платформ... для Linux это тоже работает. - person Ioannis K.; 19.03.2011
comment
Ну, это похоже на кодировку URL с использованием UTF-8; но поскольку все значения равны ‹ 128, он изоморфен ASCII (ANSI_X3.4-1968), который является кодировкой по умолчанию для вашей стратегии. Я уточнил выше. - person trashgod; 19.03.2011
comment
Это тоже не сработало. String.getBytes (UTF-8); сделал трюк для меня. Я думаю, что моя проблема заключалась в том, что я генерировал строки на лету и добавлял их непосредственно в файл .zip. Теперь я попытался создать временные файлы, которые позже добавлю в файл .zip. Это сработало для меня. Спасибо, парни! - person Ioannis K.; 22.03.2011
comment
Рад, что вы нашли решение! Пожалуйста, нажмите на серую галочку слева, чтобы принять этот ответ. - person trashgod; 22.03.2011

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

person Andrew Thompson    schedule 15.03.2011
comment
Я сообщил об ошибке. Некоторые люди говорят, что это как-то связано с паролями. Но я не ставил никакого пароля. Другие люди говорят, что это как-то связано с правами на файлы. Файл должен быть доступен для чтения и записи. Но если java предлагает эти классы... почему должны быть такие проблемы? Я вставил новый flush(), прежде чем закрыть весь поток... но все та же ошибка.. Я не понимаю:/ Есть другие идеи? - person Ioannis K.; 15.03.2011
comment
Любые другие идеи? Да я уже предлагал другую идею. Опубликовать SSCCE. - person Andrew Thompson; 18.03.2011
comment
Извини, Андрей, я не видел твой пост. Теперь у меня есть проблема (как я написал ниже), но, к сожалению, нет решения. - person Ioannis K.; 19.03.2011