我正面临一个不寻常的问题。我正在建造一个计划每5分钟运行一次的工具。
它将从特定目录中获取zip文件,并将文件(取决于文件名)提取到目标。我使用zipentry
获取zip文件中的每个文件名,然后根据需要解压缩然后将它们(zip文件,一旦我完成zip中的所有文件)备份到特定目录,然后删除zip文件。但有时(并非总是)zip文件不会被删除。因为我正在使用fileutils.forcedelete()
。我收到一个例外:无法删除文件。所以我改为使用fileutils.forcedeleteonexit()
的代码,但仍有一些文件保留在源代码中。
以下是我的代码示例:
sourceFile=new file(zipfile);
zipFile = new ZipFile(sourceFile);
zEnum = (Enumeration<ZipEntry>) zipFile.entries();
for (int a = 0; a < zipFile.size(); a++)
{
ZipEntry zE = zEnum.nextElement();
//Function uses zip4j for extracting. No streams used.
extract(String sourceZipFile, String fileNameToExtract, String outputFolder);
}
//I tried it with finally either
zipFile.close();
//Using fileutils to copy. No streams used.
copyFile(sourceFile, backup);
FileUtils.forceDeleteOnExit(sourceFile);
没有使用过流,但我有时会锁定文件(并非总是如此)。 什么似乎是这里的错误?是zip4j提取导致问题还是其他什么?我使用的是zip4j 1.3.1。
答案 0 :(得分:0)
使用apache-commons IO的FileDeleteStrategy。类似的东西:
FileDeleteStrategy.FORCE.delete(file);
<强>更新强>:
应该是在应用程序中处理IO的方式。我写了一个简单的代码,它将一个zip文件复制到一个临时zip文件中,缩短临时zip文件并在几秒后删除它。你走了:
public class ZipTest {
private static String dirPath = "/home/ubuntuuser/Desktop/";
public static void main(String[] args) throws Exception {
File myzip = new File(dirPath + "content.zip");
String tempFileStr = dirPath + "content_temp.zip";
File tempFile = new File(tempFileStr);
String unzipFolderStr = dirPath + "unzip";
copyUsingChannels(myzip, tempFile);
// copyUsingStreams(myzip, tempFile);
unZip(tempFileStr, unzipFolderStr);
Thread.sleep(3000);
tempFile.delete();
}
private static void copyUsingStreams(File myzip, File tempFile)
throws IOException, FileNotFoundException {
byte[] barray = new byte[1024];
if (!tempFile.exists())
{
tempFile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(tempFile);
FileInputStream fis = new FileInputStream(myzip);
int length = 0;
while ((length = fis.read(barray)) != -1)
{
fos.write(barray, 0, length);
}
fis.close();
fos.close();
}
public static void copyUsingChannels(final File srcFile, final File destFile) throws Exception
{
if (!destFile.exists())
{
destFile.createNewFile();
}
FileChannel source = new FileInputStream(srcFile).getChannel();
FileChannel destination = new FileOutputStream(destFile).getChannel();
source.transferTo(0, source.size(), destination);
source.close();
destination.close();
}
private static void unZip(String zipFile, String outputFolder) throws Exception {
byte[] buffer = new byte[1024];
File folder = new File(outputFolder);
if (!folder.exists()) {
folder.mkdir();
}
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
System.out.println("file unzip : " + newFile.getAbsoluteFile());
new File(newFile.getParent()).mkdirs();
if (ze.isDirectory())
{
newFile.mkdir();
ze = zis.getNextEntry();
continue;
}
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
}
}
答案 1 :(得分:0)
我认为您的问题与操作系统文件缓冲区有关,有时在您尝试删除文件时不会刷新。 您是否尝试使用sourceFile.deleteOnExit()而不是FileUtils.forceDeleteOnExit(sourceFile)? 你也可以尝试在删除之前检查sourceFile.canWrite(可能会有所帮助) 您还可以在删除之前尝试使用FileInputStream():
FileInputStream fi = new FileInputStream(sourceFile);
fi.getFD().sync();