Zip-файл не создается

У меня есть этот метод в моем приложении Springboot, которое создает 3 файла CSV (связанных с сотрудником, клиентом и зданием) внутри каталога custom_users с отметкой времени, добавленной к его имени, как показано ниже. Прямо сейчас он создает только два файла CSV (связанные с компанией и зданием), потому что я тестирую преобразование, связанное с zip-файлом, для employee_custom_file, как показано ниже.

Может ли кто-нибудь сказать мне, что я делаю неправильно при преобразовании контента, связанного с сотрудниками, в zip-файл с использованием CSVWriter (из opencsv)? Я ожидал, что один zip-файл появится с двумя другими файлами CSV, но по какой-то причине генерируются только два файла CSV.

В основном эта часть кода ниже работает не так, как я ожидал:

ZipEntry entry = new ZipEntry(file.getFileName().toString());
zos.putNextEntry(entry);
try {
    CSVWriter writer = new CSVWriter( new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
        writer.writeAll(rsDemo, true);
    }

=====================================================================

public void sendMessage(String msg) throws DaoException {

        DataSource ds = null;
        Connection conn = null;
        PreparedStatement pstmt = null;
        PreparedStatement pstmtEmployee = null;
        PreparedStatement pstmtCompany = null; 
        PreparedStatement pstmBuilding = null; 

        ResultSet rs = null;
        ResultSet rsDemo = null;
        ResultSet rsCompany = null;
        ResultSet rsBuildings = null;


         String[] parts = msg.split("#");
         String requestID = parts[0].trim();
         String userName = parts[1].trim();
         String applicationName = parts[2].trim();

        logger.info("Request ID "+requestID);
        logger.info("User Name "+userName);
        logger.info("Application Name "+applicationName);



         try {

                ds = jdbcTemplate.getDataSource();
                conn = ds.getConnection();  

                /*===========================================================================*/
                /*    Code to generate a employee CSV file              */ 
                /*===========================================================================*/
                pstmtEmployee = conn.prepareStatement(getPatientEmployeeSQL);
                pstmtEmployee.setString(1, requestID);
                rsDemo = pstmtEmployee.executeQuery();

                ResultSetMetaData rsmd = rsDemo.getMetaData();

                 FileOutputStream fos = new FileOutputStream("your_files.zip");
                 BufferedOutputStream bos = new BufferedOutputStream(fos);
                 ZipOutputStream zos = new ZipOutputStream(bos);

                 Path dir = Paths.get("/srv/custom_users", userName);
                 Files.createDirectories(dir);

                 Path file = dir.resolve("employee_custom_file" + unixTimestamp + ".csv");
                 /*try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(file))) {
                     writer.writeAll(rsDemo, true);
                 }*/
                 ZipEntry entry = new ZipEntry(file.getFileName().toString());
                 zos.putNextEntry(entry);
                 try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
                     writer.writeAll(rsDemo, true);
                 }


                 logger.info("Employee File Generated");



                 /*===========================================================================*/
                 /*    Code to generate a company CSV file                                      */ 
                 /*===========================================================================*/

                pstmtCompany = conn.prepareStatement(getCompanySQL);
                pstmtCompany.setString(1, requestID);
                rsCompany = pstmtCompany.executeQuery();

                ResultSetMetaData rsmdFacts = rsCompany.getMetaData();


                 Path filecompany = dir.resolve("company_custom_file_" + unixTimestamp + ".csv");
                 try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(filecompany))) {
                     writer.writeAll(rsCompany, true);
                 }

                 logger.info("Company CSV File Generated");


                 /*===========================================================================*/
                 /*    Code to generate a building CSV file                                 */ 
                 /*===========================================================================*/

                 pstmBuilding = conn.prepareStatement(getBuildingSQL);
                  pstmBuilding.setString(1, requestID);
                  rsBuildings = pstmBuilding.executeQuery();

                   ResultSetMetaData rsmdBuildings = rsBuildings.getMetaData();


                    Path fileBuildings = dir.resolve("building_custom_file_" + unixTimestamp + ".csv");
                     try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(fileBuildings))) {
                         writer.writeAll(rsBuildings, true);
                     }

                    logger.info("Buildings CSV File Generated");




                }
            catch(Throwable th) {
                throw new DaoException(th.getMessage(), th);
            }
            finally {
                //resource Closing statements

            }   



    }

person Tan    schedule 13.06.2019    source источник
comment
Я считаю, что ZipOutputStream не следует использовать для постоянной записи на него. Завершите запись файла и затем заархивируйте его.   -  person XtremeBaumer    schedule 13.06.2019
comment
Спасибо, но я не хочу записывать файл на диск, а затем заархивировать. По сути, я пытаюсь заархивировать содержимое csv на лету.   -  person Tan    schedule 13.06.2019
comment
Возможный дубликат Создание zip-архива на лету с файлами csv внутри   -  person XtremeBaumer    schedule 13.06.2019
comment
Да, я видел этот пост, но пытался выяснить, с какой именно проблемой я столкнулся в своем коде выше.   -  person Tan    schedule 13.06.2019


Ответы (2)


У вас есть вызов closeEntry, который отсутствует в примере кода?

Обратите внимание, что записи в выходной поток zip относятся к тому, что поддерживает выходной поток. «Запись» записи записывается в zip-поток, а не на диск, если только так не был настроен выходной поток.

От ZipOutputStream:

/**
 * Closes the current ZIP entry and positions the stream for writing
 * the next entry.
 * @exception ZipException if a ZIP format error has occurred
 * @exception IOException if an I/O error has occurred
 */
public void closeEntry() throws IOException {
person Thomas Bitonti    schedule 13.06.2019
comment
Я еще не звонил closeEntry. Я просто пытаюсь создать один zip-файл для целей тестирования. Пожалуйста, предложите, когда и куда я должен позвонить, если это необходимо для моей цели тестирования? - person Tan; 13.06.2019
comment
После записи всех данных для одной записи вызовите closeEntry, чтобы завершить запись записи. На основе примера кода, если 'writeAll' записывает все данные, предназначенные для записи, сразу после 'writeAll' будет место для вызова. - person Thomas Bitonti; 13.06.2019
comment
Итак, я добавил эти две строки writer.flush();zos.closeEntry(); чуть ниже этой строки writer.writeAll(rsDemo, true);, и все равно это не создает zip-файл. - person Tan; 13.06.2019
comment
Другая часть API вызывает 'finish()' в потоке вывода zip после того, как все записи были записаны. (И, наконец, вызов close в выходном потоке zip.) - person Thomas Bitonti; 13.06.2019
comment
В качестве альтернативы тестирования вы можете попробовать записать в выходной поток, отличный от zip, и посмотреть, успешно ли он передает данные. Это позволит отделить любые проблемы с использованием zip API от шагов передачи. - person Thomas Bitonti; 13.06.2019
comment
Спасибо. Я попробовал эту альтернативу без zip, которая прокомментирована в моем коде выше try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(file))) { writer.writeAll(rsDemo, true); }, и все работает нормально. Это проблема с почтовым индексом :( - person Tan; 13.06.2019

Я заработал. Моя эта строка кода FileOutputStream fos = new FileOutputStream("your_files.zip"); создавала проблему, так как я нигде не использовал свою переменную dir. Поэтому мне пришлось использовать его так, чтобы он работал:

OutputStream fos = Files.newOutputStream(dir.resolve("your_files.zip"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);
person Tan    schedule 14.06.2019