Сжатие CSV-файла с помощью Java создает zip-файл с меньшим количеством байтов

#java #rest #csv #zip

Вопрос:

У меня есть простой Java-код, который создает ZIP-файл, используя один CSV-файл. Код работает нормально и создает zip-файл в самый раз. Но размер zip-файла(байт) отличается от того, который я создаю с помощью инструмента для архивации Windows или чего-то вроде 7zip. Мне нужно знать, существует ли какая-либо библиотека Java, которая может создавать zip-файл, подобный тому, как Windows архивирует файл.

Фон — Мы отправляем этот zip — файл в REST API, который иногда выходит из строя с ошибкой 403-Запрещено, но когда мы архивируем файл с помощью Windows zipper или 7zip, он работает нормально. Итак, я хотел бы знать, есть ли какой-либо способ архивировать файл на Java так, как это делает Windows/7zip.

Я пытался —

  1. Встроенные функции Java для архивирования
  2. Сжатие Apache commons
  3. zip4j

напр.

 Map<String, String> env = new HashMap<>();
        // Create the zip file if it doesn't exist
        env.put("create", "true");

        URI uri = URI.create("jar:file:/C:/temp/test.zip");

        try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
            Path externalTxtFile = Paths.get("C:/temp/test.csv");
            Path pathInZipfile = zipfs.getPath("/test.csv");          
            // Copy a file into the zip file
            Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); 
        }
 

пс. Мы все еще ждем подробностей трассировки стека от поставщика API, но в то же время я ищу что-то, что может генерировать точную копию zip-файла, сгенерированного ОС, например, Windows Zipper.

Обновление Я попытался установить уровень сжатия на 1, 2,3,4,5.Это работает со всем этим. Я попробовал установить 7,8,9, он снова работает. Но с уровнем сжатия 6 он терпит неудачу. Есть идеи, в чем может быть причина? Мой код работает в ОС Unix, поэтому я считаю, что 6-это уровень по умолчанию. Но понятия не имею, как здесь может повлиять степень сжатия.

 FileOutputStream fout = new FileOutputStream("C:\temp\productcost.zip");
ZipOutputStream zout = new ZipOutputStream(output);
zout.setLevel(5); //1,2,3,4,5,7,8,9 works Level 6 - Fails with 403 Forbidden
Path file = Paths.get("C:\temp\productcost.csv");
byte[] bytes = Files.readAllBytes(file);
ZipEntry ze = new ZipEntry("productcost.csv");         
zout.putNextEntry(ze);
zout.write(bytes, 0, bytes.length);
zout.closeEntry();
zout.finish();
zout.flush();
zout.close();
 

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

Комментарии:

1. Что такое фактическая трассировка стека ошибок на сервере? Ошибка 403 - Forbidden error -это просто код ответа http.

2. Встроенная библиотека ZIP достаточно развита и совместима. Я использую его в течение многих лет без каких-либо проблем. Поэтому вам следует выяснить истинную причину этой ошибки. Когда возникает ошибка, по-прежнему ли действителен ZIP-файл? Можете ли вы проверить это с помощью 7-Zip? Если да, то проблема не в формате ZIP-файла. Если нет, то ZIP-файл может быть восстановлен в противном случае. Но ваш код для создания ZIP-файла выглядит нормально (это почти точная копия руководства по Oracle Java ).

3. Вместо этого вы можете попробовать ZipOutputStream , но, скорее всего, за ним стоит тот же код. В качестве альтернативы вы можете, например, вызвать инструмент командной строки 7-Zip как внешний процесс, но тогда вы потеряете независимость от платформы.

4. @vanje Да. Я уже перепробовал все возможные варианты создания zip-файла. Иногда службе не удается его использовать. Я также попытался использовать методы сжатия 7zip apache comms, которые снова работают нормально, но файлы не обрабатываются через API.

5. @DuncG На данный момент у меня мало подробностей от поставщика услуг. Поэтому я хотел проверить, есть ли способ сгенерировать zip-файл точно так же, как создается zip-файл Windows.

Ответ №1:

Возникла ошибка/проблема с API конечной точки, из-за которой не удалось распаковать некоторые из сжатых файлов с уровнем сжатия по умолчанию 6. Те же файлы обрабатывались с любым другим уровнем сжатия. Поскольку он нам не принадлежит, мы не знаем, что именно они исправили. Но сейчас все работает нормально. Обновлю этот ответ, если получу ответ от поставщиков API.

Ответ №2:

На самом деле вы не создаете zip-файл, вы создаете файл с .zip расширением и просто копируете в него исходное значение CSV-файла.

Для создания zip-файла на Java вы можете следовать этому руководству

Комментарии:

1. Я боюсь, что вы здесь ошибаетесь — FileSystem zipfs = FileSystems.newFileSystem(uri, env) создает файловую систему ZIP и файлы.копирование работает в пути к файловой системе ZIP.