Zip из памяти и жесткого диска различаются, что приводит к повреждению ZIP после загрузки.JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Zip из памяти и жесткого диска различаются, что приводит к повреждению ZIP после загрузки.

Сообщение Anonymous »


Проблема устранена. См. ниже.

Привет всем, я хочу реализовать загрузку в формате zip. У меня есть веб-приложение, в котором пользователь может нажать кнопку:

{{ экспортконфиг }} методы: { асинхронное преобразованиеConfigurationToZip() { // Сохраняет текущую конфигурацию в "store.config" RestResource.convertConfigurationToZip(); const configData = store.config; дождитесь нового обещания ((решить) => setTimeout(решить, 2000)); // Blob представляет собой необработанные двоичные данные const blob = new Blob ([configData], {type: 'application/zip'}); // Используем файловую загрузку, чтобы инициировать загрузку saveAs(blob, 'конфигурация') В RestResource вызывается следующая функция:

convertConfigurationToZip: () => { аксиомы .get("http://localhost:8080/api/conversion/co ... tionToZip/") .then((ответ: любой) => { console.log(ответ.данные); store.config = ответ.данные; }) .catch((ошибка: любая) => { console.log(ошибка); }) } Вызываемый контроллер выглядит следующим образом:

контроллер пакета; импортировать io.swagger.annotations.*; импортировать jakarta.annotation.Resource; импортировать jakarta.ws.rs.GET; импортировать jakarta.ws.rs.Path; импортировать jakarta.ws.rs.container.AsyncResponse; импорт jakarta.ws.rs.container.Suspended; импортировать jakarta.ws.rs.core.Response; службы импорта.ConversionService; импортировать java.util.concurrent.ExecutorService; импортировать java.util.concurrent.Executors; // Этот контроллер следует использовать для создания zip-файлов, содержащих конфигурацию ProCake. @Api(tags = «Контроллер преобразований», авторизации = { @Authorization(value = «basicAuth») }) @Path("/преобразование") общедоступный класс ConversionController { @Ресурс Служба-исполнительСервис-исполнитель; @ApiOperation(value = «Преобразовать конфигурацию в Zip») @ApiResponses({ @ApiResponse(code = 200, message = «Настроить как Zip»), @ApiResponse(code = 503, message = «ProCAKE не запущен/настроен неправильно») }) @ПОЛУЧАТЬ @Path("/convertConfigurationToZip") public void ConvertConfigurationToZip(@Приостановленный окончательный ответ AsyncResponse) { executorService = Executors.newSingleThreadExecutor(); executorService.submit(() -> { пытаться { response.resume(Response.status(200).entity(new ConversionService().convertConfigurationToZip()).build()); } поймать (Исключение e) { ответ.резюме (е); } исполнительService.shutdown(); }); } } Сервис, в котором обрабатывается ZIP-файл, выглядит следующим образом:

пакетные службы; импортировать de.uni_trier.wi2.procake.data.model.Model; импорт de.uni_trier.wi2.procake.data.model.ModelFactory; import de.uni_trier.wi2.procake.similarity.SimilarityModel; import de.uni_trier.wi2.procake.similarity.SimilarityModelFactory; импортировать de.uni_trier.wi2.procake.utils.io.IOUtil; импортировать org.apache.commons.compress.archivers.zip.ZipArchiveEntry; импортировать org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; импортировать org.apache.commons.io.IOUtils; импортировать org.apache.jena.sparql.exec.RowSet; импортировать java.io.*; импортировать java.nio.file.Files; импортировать java.nio.file.Paths; импортировать java.util.ArrayList; импортировать java.util.Arrays; импортировать java.util.List; импортировать java.util.zip.ZipInputStream; общедоступный класс ConversionService { public byte[] ConvertConfigurationToZip() выдает IOException { пытаться { // Создать ZIP на жестком диске Список listOfFiles = новый ArrayList(); Привет файлу = новый файл("pathToFile"); Мир файлов = новый файл («pathToFile»); listOfFiles.add(привет); listOfFiles.add(мир); IOUtil.createZipFile("pathToZip", listOfFiles); // --------------------- // Создать ZIP-файл в памяти ByteArrayOutputStream baos = IOUtil.createZipFileInMemory(listOfFiles); ; // --------------------- // Сравниваем оба ZIP-файла byte[] zipContentHardDrive = Files.readAllBytes(Paths.get("pathToFile")); byte[] zipContentMemory = baos.toByteArray(); int minLength = Math.min(zipContentMemory.length, zipContentHardDrive.length); если (!Arrays.equals( Arrays.copyOf(zipContentMemory, minLength), Arrays.copyOf(zipContentHardDrive, minLength))) { throw new IOException("Zip-файлы разные."); } // --------------------- вернуть zipContentMemory; }catch (Исключение е) { System.out.println("Не удалось создать ZIP-файл"); } вернуть ноль; } } И наконец, прежде чем я подробнее расскажу о своей проблеме, вот методы IOUtil:

public static ByteArrayOutputStream createZipFileInMemory(List files) выдает IOException { ByteArrayOutputStream byteArrayOutputStream = новый ByteArrayOutputStream (); ZipArchiveOutputStream zipArchiveOutputStream = новый ZipArchiveOutputStream( byteArrayOutputStream); for (Файл файл: файлы) { addZipEntry (zipArchiveOutputStream, файл); } zipArchiveOutputStream.finish(); вернуть byteArrayOutputStream; } Private static void addZipEntry (ArchiveOutputStream archiveOutputStream, File file) выдает IOException { Строковое имя записи = file.getName(); ArchiveEntry archiveEntry = новый ZipArchiveEntry (файл, имя записи); archiveOutputStream.putArchiveEntry(archiveEntry); если (файл.isFile()) { Files.copy(file.toPath(), archiveOutputStream); } archiveOutputStream.closeArchiveEntry(); } createZipFile работает нормально. Моя проблема в том, что zip-файл, который я получаю при загрузке, примерно на 200 байт больше, чем тот, который я создаю непосредственно на своем жестком диске. Я также не могу открыть большой zip-файл. Открыв большой zip-файл с помощью vim, я вижу, что его содержимое совершенно отличается от содержимого меньшего zip-файла:

Застежка-молния меньшего размера: " zip.vim версии v33 " Просмотр zip-файла pathToZip " Выберите файл курсором и нажмите ENTER

привет.txt мир.txt

а вот покрупнее: PK^C^D^T^@^H^H^H^@����W^@^@^@^@^@^@^@^@^@^@^@^@ ^@5^@ hello.txtUT^M^@^G���eִ�e���e

Я не знаю, неправильный ли у меня метод создания zip-файла в памяти или что-то не так с передачей в store.config. Еще примечательно то, что zipContentHardDrive и zipContentMemory отличаются: zipContentЖесткий диск: [80, 75, 3, 4, 20, 0, 0, 8, 8, 0, -72, -114, -103, 87, 32, 48, 58, 54, 8, 0, 0, 0, 6, 0, 0, 0, 9, 0, 53, 0, 104, 101, 108, 108, 111, 46, 116, 120, 116, 85, 84, 13, 0, 7, -99, -77, -119 , 101, -42, -76, -119, 101, -99, -77, -119, 101, 10, 0, 32, 0, 0, 0, 0, 0, 1, 0, 24, 0, - 106, 85, -35, -18, 82, 55, -38, 1, 4, 18, -88, -87, 83, 55, -38, 1, -128, 76, -114, -18, 82 , 55, -38, 1, -53, 72, -51, -55, -55, -25, 2, 0, еще +322]

zipContentMemory: [80, 75, 3, 4, 20, 0, 8, 8, 8, 0, -72, -114, -103, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 53, 0, 104, 101, 108, 108, 111, 46, 116, 120, 116, 85, 84, 13, 0, 7, -99, -77, -119 , 101, -42, -76, -119, 101, -99, -77, -119, 101, 10, 0, 32, 0, 0, 0, 0, 0, 1, 0, 24, 0, - 106, 85, -35, -18, 82, 55, -38, 1, 4, 18, -88, -87, 83, 55, -38, 1, -128, 76, -114, -18, 82 , 55, -38, 1, -53, 72, -51, -55, -55, -25, 2, 0, еще +354]

Я не уверен, что это потому, что zip-файлы обычно различаются, находятся ли они в памяти, а когда нет.

Я был бы очень признателен, если бы кто-нибудь помог мне понять и решить мою проблему. Большое спасибо, что нашли время!

Обновление 1 После следующего теста я обнаружил, что по неизвестным причинам метод createZipFileInMemory не работает должным образом в CoonversionService.

@Test public void testCreateZipFileInMemoryWithFiles() выдает IOException { IOUtil.writeFile(график, PATH_GRAPH_TXT); IOUtil.writeFile(график, PATH_GRAPH_XML); Файл fileText = новый файл (PATH_GRAPH_TXT); Файл fileXML = новый файл (PATH_GRAPH_XML); List listOfFiles = новый ArrayList(); listOfFiles.add(fileText); listOfFiles.add(fileXML); ByteArrayOutputStream zipFileInMemory = IOUtil.createZipFileInMemory(listOfFiles); AssertNotNull (zipFileInMemory); // Теперь проверим, действительно ли данные, хранящиеся в памяти, являются правильным Zip-файлом // Поэтому давайте создадим настоящий Zip-файл на нашем жестком диске IOUtil.createZipFile(PATH_CREATED_ZIP, listOfFiles); // Читаем содержимое созданного zip-файла byte[] factZipContent = Files.readAllBytes(Paths.get(PATH_CREATED_ZIP)); // Сравниваем содержимое файлов в zip-архиве ZipInputStream dataOfMemoryZip = новый ZipInputStream (новый ByteArrayInputStream (zipFileInMemory.toByteArray ())); ZipInputStream dataOfHardDriveZip = новый ZipInputStream (новый ByteArrayInputStream (actualZipContent)); ZipEntry MemoryEntry; ZipEntry HardDriveEntry; while ((memoryEntry = dataOfMemoryZip.getNextEntry()) != null) { hardDriveEntry = dataOfHardDriveZip.getNextEntry(); AssertEquals(memoryEntry.getName(), hardDriveEntry.getName()); byte[] ожидаемыйFileContent = IOUtils.toByteArray(dataOfMemoryZip); byte[] factFileContent = IOUtils.toByteArray(dataOfHardDriveZip); AssertArrayEquals (expectedFileContent, factFileContent); } } здесь содержимое всегда одинаковое. Я не понимаю, почему в классе ConversionService содержимое разное, ведь я использую те же файлы и те же методы.

Обновление 2 По запросу вот шестнадцатеричный дамп загруженного zip-файла: Вот шестнадцатеричный дамп zip-архива, который я получил после загрузки:

504b0304140000080800efbfbdefbfbdefbfbd5720303a36080000000600 00000900350068656c6c6f2e74787455540d0007efbfbdefbfbdefbfbd65 d6b4efbfbd65efbfbdefbfbdefbfbd650a0020000000000001001800efbf bd55efbfbdefbfbd5237efbfbd010412efbfbdefbfbd5337efbfbd01efbf bd4cefbfbdefbfbd5237efbfbd01efbfbd48efbfbdefbfbdefbfbdefbfbd 0200504b0304140000080800efbfbdefbfbdefbfbd57efbfbd6138efbfbd 080000000600000009003500776f726c642e74787455540d0007efbfbdef bfbdefbfbd65efbfbdefbfbdefbfbd65efbfbdefbfbdefbfbd650a002000 000000000100180009efbfbd28efbfbd5237efbfbd01efbfbdefbfbdefbf bdefbfbd5237efbfbd01efbfbd5aefbfbdefbfbd5237efbfbd012befbfbd 2fefbfbd49efbfbd0200504b01021400140000080800efbfbdefbfbdefbf bd5720303a36080000000600000009002d00000000000000000000000000 000068656c6c6f2e7478745554050007efbfbdefbfbdefbfbd650a002000 0000000001001800efbfbd55efbfbdefbfbd5237efbfbd010412efbfbdef bfbd5337efbfbd01efbfbd4cefbfbdefbfbd5237efbfbd01504b01021400 140000080800efbfbdefbfbdefbfbd57efbfbd6138efbfbd080000000600 000009002d000000000000000000000064000000776f726c642e74787455 54050007efbfbdefbfbdefbfbd650a002000000000000100180009efbfbd 28efbfbd5237efbfbd01efbfbdefbfbdefbfbdefbfbd5237efbfbd01efbf bd5aefbfbdefbfbd5237efbfbd01504b05060000000002000200efbfbd00 0000efbfbd0000000000

а вот шестнадцатеричный дамп рабочего zip-файла:

504b0304140000080800b88e995720303a36080000000600000009003500 68656c6c6f2e74787455540d00079db38965d6b489659db389650a002000 00000000010018009655ddee5237da010412a8a95337da01804c8eee5237 da01cb48cdc9c9e70200504b0304140000080800c08e9957a86138dd0800 00000600000009003500776f726c642e74787455540d0007a9b38965abb3 8965a9b389650a002000000000000100180009ba28f65237da0183dглухой6 5237da01805ab5f55237da012bcf2fca49e10200504b0102140014000008 0800b88e995720303a36080000000600000009002d000000000000000000 00000000000068656c6c6f2e74787455540500079db389650a0020000000 0000010018009655ddee5237da010412a8a95337da01804c8eee5237da01 504b01021400140000080800c08e9957a86138dd08000000060000000900 2d000000000000000000000064000000776f726c642e7478745554050007 a9b389650a002000000000000100180009ba28f65237da0183ddeaf65237 da01805ab5f55237da01504b05060000000002000200c8000000c8000000 0000

Устранение проблемы: Вот изменения:

методы: { асинхронное преобразованиеConfigurationToZip() { если (this.conversionInProgress) { возвращаться; } this.conversionInProgress = true; // Сохраняет текущую конфигурацию в "store.config" константный ответ = ждут RestResource.convertConfigurationToZip(); // Blob представляет собой необработанные двоичные данные const blob = new Blob([response.data], {type: 'application/zip'}); // # saveAs(blob, 'config.zip'); this.conversionInProgress = ложь; } и

convertConfigurationToZip: async () => { return axios.get("http://localhost:8080/api/conversion/co ... tionToZip/", { responseType: "blob", // Убедитесь, что ответ рассматривается как большой двоичный объект }) .then((ответ) => { обратный ответ; // Возвращаем весь объект ответа Axios }) .catch((ошибка) => { console.error(ошибка); ошибка выброса; // Повторно выдаем ошибку, чтобы обработать ее соответствующим образом в контексте вызова }); } Я предполагаю, что const configData = store.config был строкой, а не двоичными данными.
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»