private static boolean mv0( final java.io.File src, final java.io.File dst, final ArchiveDetector detector) { boolean ok = true; if (src.isDirectory()) { final long srcLastModified = src.lastModified(); final boolean srcIsArchived = src instanceof File && ((File) src).getInnerArchive() != null; final boolean dstIsArchived = dst instanceof File && ((File) dst).getInnerArchive() != null; final boolean srcIsGhost = srcIsArchived && srcLastModified <= 0; if (!srcIsGhost || !dstIsArchived || !File.isLenient()) dst.mkdir(); final String[] members = src.list(); if (!srcIsArchived && dstIsArchived) { // Create sorted entries if writing a new archive file. // This is courtesy only, so natural order is sufficient. Arrays.sort(members); } for (int i = 0, l = members.length; i < l; i++) { final String member = members[i]; ok &= mv0(detector.createFile(src, member), detector.createFile(dst, member), detector); } if (!srcIsGhost) ok &= dst.setLastModified(srcLastModified); } else if (src.isFile()) { // !isDirectory() try { cp(true, src, dst); } catch (IOException ex) { ok = false; } } else { ok = false; // don't move special files! } return ok && src.delete(); // only unlink if ok! }
/** Unchecked parameters version. */ private static void cp_r0( final boolean preserve, final java.io.File src, final java.io.File dst, final ArchiveDetector srcDetector, final ArchiveDetector dstDetector) throws IOException { if (src.isDirectory()) { final long srcLastModified = src.lastModified(); final boolean srcIsArchived = src instanceof File && ((File) src).getInnerArchive() != null; final boolean dstIsArchived = dst instanceof File && ((File) dst).getInnerArchive() != null; final boolean srcIsGhost = srcIsArchived && srcLastModified <= 0; if (!srcIsGhost || !dstIsArchived || !File.isLenient()) if (!dst.mkdir() && !dst.isDirectory()) throw new IOException("destination is not a directory"); final String[] members = src.list(); if (!srcIsArchived && dstIsArchived) { // Create sorted entries if writing a new archive. // This is a courtesy only, so natural order is sufficient. Arrays.sort(members); } for (int i = 0, l = members.length; i < l; i++) { final String member = members[i]; cp_r0( preserve, srcDetector.createFile(src, member), dstDetector.createFile(dst, member), srcDetector, dstDetector); } if (preserve && !srcIsGhost) if (!dst.setLastModified(srcLastModified)) throw new IOException("cannot set last modification time"); } else if (src.isFile() && (!dst.exists() || dst.isFile())) { cp0(preserve, src, dst); } else { throw new IOException("cannot copy non-existent or special files"); } }
/** * Removes the entire directory tree represented by the parameter, regardless whether it's a file * or directory, whether the directory is empty or not or whether the file or directory is * actually an archive file, an entry in an archive file or not enclosed in an archive file at * all. * * <p>The name of this method is inspired by the Unix command line utility <code>rm</code> with * the <code>-r</code> option to operate recursively. * * <p>This file system operation is <em>not</em> atomic. * * @return Whether or not the entire directory tree was successfully removed. */ public static boolean rm_r(final java.io.File file) { boolean ok = true; if (file.isDirectory()) { // Note that listing the directory this way will cause a recursive // deletion if the directory is actually an archive file. // Although this does not provide best performance (the archive // file could simply be removed like an ordinary file), it ensures // that the state cached by the ArchiveController is not bypassed // and hence prevents a potential bug. java.io.File[] members = file.listFiles(); for (int i = members.length; --i >= 0; ) ok &= rm_r(members[i]); } return ok && file.delete(); }