/** * Copies a source file to a destination file, optionally preserving the source's last * modification time. We already have an input stream to read the source file, but we know nothing * about the destination file yet. Note that this method <em>never</em> closes the given input * stream! * * @throws FileNotFoundException If either the source or the destination cannot get accessed. * @throws InputIOException If copying the data fails because of an IOException in the source. * @throws IOException If copying the data fails because of an IOException in the destination. */ private static void cp0( final boolean preserve, final java.io.File src, final InputStream in, final java.io.File dst) throws IOException { try { if (dst instanceof File) { final File dstFile = (File) dst; dstFile.ensureNotVirtualRoot("cannot write"); final String dstEntryName = dstFile.getEnclEntryName(); if (dstEntryName != null) { cp0(preserve, src, in, dstFile.getEnclArchive().getArchiveController(), dstEntryName); return; } } } catch (RfsEntryFalsePositiveException dstIsNotArchive) { } // Treat the destination like a regular file. final OutputStream out = new java.io.FileOutputStream(dst); try { Streams.cat(in, out); } finally { out.close(); } if (preserve && !dst.setLastModified(src.lastModified())) throw new IOException(dst.getPath() + " (cannot preserve last modification time)"); }
/** * Removes any <code>"."</code> and <code>".."</code> directories from the * path wherever possible. * * @param file The file instance which's path is to be normalized. * @return <code>file</code> if it was already in normalized form. Otherwise, an object which's * runtime class is guaranteed to be <code>java.io.File</code>. */ public static java.io.File normalize(final java.io.File file) { final String path = file.getPath(); final String newPath = Paths.normalize(path, File.separatorChar); return newPath != path // mind contract of Paths.normalize! ? new java.io.File(newPath) : file; }
/** @see File#contains */ public static boolean contains(java.io.File a, java.io.File b) { a = getCanOrAbsFile(a); b = getCanOrAbsFile(b); return contains(a.getPath(), b.getPath()); }
/** * Copies a source file to a destination file, optionally preserving the source's last * modification time. We know that the source file appears to be an entry in an archive file, but * we know nothing about the destination file yet. * * <p>Note that this method synchronizes on the class object in order to prevent dead locks by two * threads copying archive entries to the other's source archive concurrently! * * @throws FalsePositiveException If the source or the destination is a false positive and the * exception cannot get resolved within this method. * @throws InputIOException If copying the data fails because of an IOException in the source. * @throws IOException If copying the data fails because of an IOException in the destination. */ private static void cp0( final boolean preserve, final ArchiveController srcController, final String srcEntryName, final java.io.File dst) throws IOException { // Do not assume anything about the lock status of the controller: // This method may be called from a subclass while a lock is acquired! // assert !srcController.readLock().isLocked(); // assert !srcController.writeLock().isLocked(); try { try { if (dst instanceof File) { final File dstFile = (File) dst; dstFile.ensureNotVirtualRoot("cannot write"); final String dstEntryName = dstFile.getEnclEntryName(); if (dstEntryName != null) { cp0( preserve, srcController, srcEntryName, dstFile.getEnclArchive().getArchiveController(), dstEntryName); return; } } } catch (RfsEntryFalsePositiveException isNotArchive) { // Both the source and/or the destination may be false positives, // so we need to use the exception's additional information to // find out which controller actually detected the false positive. if (isNotArchive.getController() == srcController) throw isNotArchive; // not my job - pass on! } final InputStream in; final long time; srcController.readLock().lock(); try { in = srcController.createInputStream0(srcEntryName); // detects false positives! time = srcController.lastModified(srcEntryName); } finally { srcController.readLock().unlock(); } // Treat the destination like a regular file. final OutputStream out; try { out = new java.io.FileOutputStream(dst); } catch (IOException ex) { try { in.close(); } catch (IOException inFailure) { throw new InputIOException(inFailure); } throw ex; } cp(in, out); if (preserve && !dst.setLastModified(time)) throw new IOException(dst.getPath() + " (cannot preserve last modification time)"); } catch (ArchiveEntryFalsePositiveException ex) { assert srcController == ex.getController(); // Reroute call to the source's enclosing archive controller. cp0( preserve, srcController.getEnclController(), srcController.enclEntryName(srcEntryName), dst); } }