#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. закройте файл после завершения его использования.