ZIP-файл поврежден при загрузке из вложения SOAP

Я использую веб-службу, которая помогает мне получать файлы из концентратора сообщений. Тип файла может быть XML или ZIP.

Для ZIP-файлов тип содержимого — двоичный.

У меня есть этот кусок кода:

private String extractPayload(String filePath, AttachmentPart attach){

        FileOutputStream fileStream = null;

        try {
              DataHandler handler;
              handler = attach.getDataHandler();

              File f = new File(filePath);

              fileStream = new FileOutputStream(filePath);

              handler.writeTo(fileStream);

              fileStream.flush();

        } catch (Exception ex) {

              logger.info("####Exception:" + ex.getMessage());

        } finally {

              if (fileStream != null)
                    fileStream.close();

        }

        return filePath;

}

Теперь код отлично работает для извлечения XML-файлов, хотя в случае с ZIP-файлами файл оказывается поврежденным. Я загрузил тот же файл с помощью файловой утилиты из центра обмена сообщениями и обнаружил, что размер файла, который я извлекаю через вложение SOAP, примерно на 4 байта больше, чем его фактический размер.

Обновление: кодировка вложения 7-битная (если это может мешать), в то время как другое вложение, содержащее другой почтовый индекс, закодировано как Quote-printable. Оба почтовых индекса загружаются из одной и той же веб-службы (хотя они различаются кодировкой), и оба оказываются поврежденными.

Редактировать: я твердо уверен, что проблема связана с кодировкой, в которой я получаю файл, и вот сравнение между фактическим файлом и полученным файлом вложения.

Фактический размер файла: 9031 байт Размер файла полученного вложения: 9066 байт

Я попытался сравнить оба файла в редакторе документов, чтобы найти различия между ними. Различия между исходным файлом и загруженным вложенным файлом (двоичный редактор):

ed изменено на 3f, db изменено на 3f, d6 изменено на 3f, 85 изменено на 3f, d0 изменено на 3f,

и так далее.

Zip-файл содержит PDF-файл и XML-файл.

Начальная строка обоих файлов похожа, начиная с PK


person Priyanshu Jha    schedule 26.03.2013    source источник


Ответы (1)


Я предполагаю, что ваш buf представляет собой массив 2048 байт. Попробуйте следующее изменение

Заменять

fileStream.write(buf);

с этим

fileStream.write(buf, 0, n);

Это нужно исправить на тот случай, если при последнем чтении вы получите только 1024 байта, а остальные 1024 байта buf будут иметь мусорные значения, будут записаны в файл и повредят его.

person shazin    schedule 27.03.2013
comment
Я думаю, вы имеете в виду write(buf, 0, n), но предпосылка верна. - person Jon Skeet; 27.03.2013
comment
Пробовал уже. Проблема в том, что zis.read() выдает исключение java.util.ZipException: Invalid block action. Кроме того, entry.getSize() (для получения размера записи Zip) возвращает -1. - person Priyanshu Jha; 27.03.2013
comment
@PriyanshuJha: Где это выбрасывается? Вы должны по крайней мере внести изменение, о котором говорил Шазин... потому что в настоящее время это очень реальная ошибка. - person Jon Skeet; 27.03.2013
comment
@JonSkeet: я исправил эту ошибку. Выдает исключение в zis.read(). Я где-то читал, что могу выполнить zis.read(), чтобы проверить, получает ли он действительный почтовый поток, если он возвращает -1 или выдает исключение, это может означать, что поток не является допустимым почтовым потоком. Я также напечатал MIME-типы вложений и значения: MIME:Content-Type : application/binary MIME:Content-Transfer-Encoding : 7Bit Я подозреваю, что содержимое отправляется в неправильной кодировке!! - person Priyanshu Jha; 27.03.2013
comment
Нужна дополнительная информация о вашем ZIP-файле. Если 7-битный код закодирован, вам лучше сначала его декодировать, прежде чем пытаться его прочитать. - person shazin; 27.03.2013
comment
@PriyanshuJha: Да, это похоже на проблему. На данный момент я бы полностью избавился от части ZipInputStream - просто запишите необработанные данные, которые вы получаете от handler.getDataSource().getInputStream(), в файл, и сравните их с исходным zip-файлом... затем отредактируйте свой вопрос с соответствующей информацией. - person Jon Skeet; 27.03.2013
comment
@JonSkeet, я сделал это. Это был мой первый подход, а позже я попытался перейти к Zis, но безрезультатно. Я редактирую вопрос, добавляя больше деталей к разнице между двумя файлами. - person Priyanshu Jha; 27.03.2013
comment
@PriyanshuJha: Если бы вы знали, что уже есть разница, почему вы начали использовать ZipInputStream? Конечно, первое нужно убедиться, что вы можете правильно передать байты из A в B. Затем вы начинаете интерпретировать эти байты как zip-файл. - person Jon Skeet; 27.03.2013
comment
@JonSkeet Сначала я не знал, что отправляется другая кодировка. Я подумал, может поток пишется не так, как положено, и поэтому перешел на ЗИС (Наивная ошибка). Позже, когда я был уверен, что есть какая-то другая проблема, я углубился в тип кодирования потока и то, каким должен быть ZIP, дойдя до этого момента. Я обновил вопрос, чтобы отразить мои открытия. С потоками работаю впервые и поэтому не слишком разбираюсь в разных нюансах. Так что извините меня за наивные заявления и действия. - person Priyanshu Jha; 27.03.2013
comment
@PriyanshuJha: В вашем сообщении говорится о персонажах, но zip-файл — это двоичные данные. Вы не должны пытаться загрузить его в текстовый редактор, чтобы сравнить оригинал с результатом. Вы должны использовать редактор двоичных файлов. Вы также должны предоставить больше информации о веб-сервисе - он вообще находится под вашим контролем? Может быть, это сломано? - person Jon Skeet; 27.03.2013
comment
@JonSkeet Нет, веб-служба принадлежит другой организации. У нас просто есть их WSDL. По сути, это концентратор сообщений, который хранит файлы в виде сообщений и выступает в качестве промежуточной стороны для обмена данными. Ранее они предоставили настольное приложение, которое выполняло удаленные вызовы, но запускалось довольно медленно. Как только они представили нам веб-сервисы, мы теперь переходим на использование их веб-сервисов. Их WSDL не имеет возможности указать кодировку, хотя вы можете указать тип контента. Мы указываем тип контента как Binary. - person Priyanshu Jha; 27.03.2013
comment
@JonSkeet Кроме того, странно то, что когда мы получаем больше сообщений, тип кодировки каждый раз меняется. То есть у меня было 2 молнии на хабе, я сделал два звонка. При первом вызове тип кодировки — 7, но при следующем вызове он показал Quote-printable. - person Priyanshu Jha; 27.03.2013
comment
@PriyanshuJha: Звучит довольно глупо. Я предлагаю вам связаться с этой организацией - похоже, это довольно специфическая проблема на их стороне. - person Jon Skeet; 27.03.2013
comment
@JonSkeet да, даже я думаю, что это проблема с их стороны. Хотя я отредактировал вопрос, чтобы отразить изменения двоичных данных, на случай, если вы захотите взглянуть. Я был стажером здесь, и этот проект был дан в самом конце стажировки. Сегодня мой последний день, полагаю, мне придется оставить его здесь. В любом случае!! Спасибо за всю помощь! и извините за беспокойство!! - person Priyanshu Jha; 27.03.2013