5757import java .time .chrono .ChronoLocalDateTime ;
5858import java .time .chrono .ChronoZonedDateTime ;
5959import java .util .ArrayList ;
60+ import java .util .Arrays ;
6061import java .util .Collection ;
6162import java .util .Collections ;
6263import java .util .Date ;
@@ -297,7 +298,9 @@ private static void checkFileExists(final File file, final String name) throws F
297298 if (file .exists ()) {
298299 throw new IllegalArgumentException ("Parameter '" + name + "' is not a file: " + file );
299300 }
300- throw new FileNotFoundException ("Source '" + file + "' does not exist" );
301+ if (!Files .isSymbolicLink (file .toPath ())) {
302+ throw new FileNotFoundException ("Source '" + file + "' does not exist" );
303+ }
301304 }
302305 }
303306
@@ -504,6 +507,13 @@ public static File[] convertFileCollectionToFileArray(final Collection<File> fil
504507 * not guaranteed that the operation will succeed. If the modification operation fails, it falls back to
505508 * {@link File#setLastModified(long)}. If that fails, the method throws IOException.
506509 * </p>
510+ * <p>
511+ * Symbolic links in the source directory are copied to new symbolic links in the destination
512+ * directory that point to the original target. The target of the link is not copied unless
513+ * it is also under the source directory. Even if it is under the source directory, the new symbolic
514+ * link in the destination points to the original target in the source directory, not to the
515+ * newly created copy of the target.
516+ * </p>
507517 *
508518 * @param srcDir an existing directory to copy, must not be {@code null}.
509519 * @param destDir the new directory, must not be {@code null}.
@@ -816,7 +826,7 @@ public static void copyFile(final File srcFile, final File destFile, final boole
816826 * @param srcFile an existing file to copy, must not be {@code null}.
817827 * @param destFile the new file, must not be {@code null}.
818828 * @param preserveFileDate true if the file date of the copy should be the same as the original.
819- * @param copyOptions options specifying how the copy should be done, for example {@link StandardCopyOption}..
829+ * @param copyOptions options specifying how the copy should be done, for example {@link StandardCopyOption}.
820830 * @throws NullPointerException if any of the given {@link File}s are {@code null}.
821831 * @throws FileNotFoundException if the source does not exist.
822832 * @throws IllegalArgumentException if source is not a file.
@@ -825,7 +835,7 @@ public static void copyFile(final File srcFile, final File destFile, final boole
825835 * @see #copyFileToDirectory(File, File, boolean)
826836 * @since 2.8.0
827837 */
828- public static void copyFile (final File srcFile , final File destFile , final boolean preserveFileDate , final CopyOption ... copyOptions ) throws IOException {
838+ public static void copyFile (final File srcFile , final File destFile , final boolean preserveFileDate , CopyOption ... copyOptions ) throws IOException {
829839 Objects .requireNonNull (destFile , "destination" );
830840 checkFileExists (srcFile , "srcFile" );
831841 requireCanonicalPathsNotEquals (srcFile , destFile );
@@ -834,10 +844,18 @@ public static void copyFile(final File srcFile, final File destFile, final boole
834844 checkFileExists (destFile , "destFile" );
835845 requireCanWrite (destFile , "destFile" );
836846 }
847+
848+ final boolean isSymLink = Files .isSymbolicLink (srcFile .toPath ());
849+ if (isSymLink && !Arrays .asList (copyOptions ).contains (LinkOption .NOFOLLOW_LINKS )) {
850+ final List <CopyOption > list = new ArrayList <CopyOption >(Arrays .asList (copyOptions ));
851+ list .add (LinkOption .NOFOLLOW_LINKS );
852+ copyOptions = list .toArray (new CopyOption [0 ]);
853+ }
854+
837855 Files .copy (srcFile .toPath (), destFile .toPath (), copyOptions );
838856
839857 // On Windows, the last modified time is copied by default.
840- if (preserveFileDate && !setTimes (srcFile , destFile )) {
858+ if (preserveFileDate && !isSymLink && ! setTimes (srcFile , destFile )) {
841859 throw new IOException ("Cannot set the file time." );
842860 }
843861 }
0 commit comments