Ошибка Java при добавлении и создании zip-файлов: процесс не может получить доступ к файлу

#java #jar #zip #uri #nio

#java #jar #zip #uri #nio

Вопрос:

Я создал Java-программу с использованием Java ZipFileSystem (Java 8) для архивирования файлов в zip-файлы. Я думал, что это будет просто и просто, но после некоторого запуска он выдает «java.nio.file.Исключение FileSystemException «. Фрагмент кода ниже:

         ......
        fileName = fileName   "_";
        int zipFileNameMidPart;
        try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(sourceDir, getFilter(sourceDir)))
        {
          for(Path path : dirStream)
          {
            lastModified.setTimeInMillis(Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS).toMillis());
            zipFileNameMidPart = fileName.equalsIgnoreCase("salesfaxes") ? lastModified.get(Calendar.MONTH) 1 : (lastModified.get(Calendar.MONTH)/3) 1;
            zipFileName = fileName lastModified.get(Calendar.YEAR) "_" zipFileNameMidPart ".zip";
            zipFile = Paths.get(srcDirTmp, zipFileName);
            addToZipArchive(path, zipFile, !Files.exists(zipFile), tmpMoveDir);
            
            //Move archived file to the temp directory.
            currentBackupFile = tmpMoveDir.resolve(path.getFileName());
            logger.info("Moving " path " to " currentBackupFile);
            Files.move(path, currentBackupFile, StandardCopyOption.REPLACE_EXISTING);
          }
        }//try
  
protected void addToZipArchive(Path fileToBeArchived, Path zipArchive, boolean create, Path tmpBackupDir) throws Exception
      {
        /* Define ZIP File System Properies in HashMap */    
        Map<String, String> zip_properties = new HashMap<>(); 
        /* set create to true if you want to create a new ZIP file */
        zip_properties.put("create", Boolean.toString(create));
        /* specify encoding to UTF-8 */
        zip_properties.put("encoding", "UTF-8");        
        /* Locate File on disk for creation */
        URI zip_disk = URI.create("jar:file:/"   zipArchive.toString().replace("\", "/"));
        totalCnt  ;
        /* Create ZIP file System */
        try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) 
        {
          /* Path inside ZIP File */
          Path pathInZipfile = zipfs.getPath(fileToBeArchived.getFileName().toString());
          boolean copyOk = true;
          try
          {
            logger.info("Adding " fileToBeArchived.toString() " to " (create?"new ":"existing ") "zip file " zipArchive.toString());
                /* Add file to archive */
                Files.copy(fileToBeArchived, pathInZipfile, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); 
          }
          catch(Exception e)
          {
                copyOk = false;
            logger.log(Level.SEVERE, e.getMessage(), e);
          }
          if(copyOk)
          {         
            if(create)
              createCnt  ;
            else
              addCnt  ;    
          }
          else
          {
            logger.severe("Skip file " fileToBeArchived "! Error encounted while archiving it.");
            skippedCnt  ;
          }
        }
      }
  

Трассировка стека:

 SEVERE: Error occured!
java.nio.file.FileSystemException: C:tempbolsbols_2017_4.zip: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
at java.nio.file.Files.delete(Files.java:1126)
at com.sun.nio.zipfs.ZipFileSystem.sync(ZipFileSystem.java:1301)
at com.sun.nio.zipfs.ZipFileSystem.close(ZipFileSystem.java:277)
at ZipArchiveUtil.addToZipArchive(ZipArchiveUtil.java:177)
at ZipArchiveUtil.processDirs(ZipArchiveUtil.java:282)
at ZipArchiveUtil.main(ZipArchiveUtil.java:392)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:61)
  

Каталоги довольно большие, содержащие десятки тысяч файлов tif. И zip-файлы также могут стать очень большими (размер файла превышает гигабайт).
Я пытался запускать программу ночью и в выходные дни, но после запуска некоторое время получал ту же ошибку.
Также скопировал env на другой компьютер, тот же результат.
Похоже, что программа все еще удерживает zip-файл при попытке добавить в него новый файл… Чего мне не хватает? Немного погуглил, не нашел много информации.

Еще одна странная вещь, время от времени программа «останавливается», ничего не делая. Если я нажму CTRL Z, он снова начнет обработку. Я проверил в диспетчере задач, нет использования процессора и диска, пока он находится на «паузе».

Любые подсказки / предложения приветствуются.

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

1. Закройте файлы, когда закончите.

2. Вы имеете в виду эту строку? try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) . Это инструкция try-with-resources, означающая, что каждый ресурс закрывается в конце инструкции.

3. По-прежнему похоже, что файл не закрывается. Попробуйте закрыть и посмотреть, не поможет ли это что-нибудь.

4. Я немного потерялся… Не могли бы вы указать, какой файл и куда следует добавить оператор close()? Спасибо.

5. Я бы поставил это после if( OK){ … } else {… }; zipfs.close(); ie. закройте файл после завершения его использования.