@@ -103,44 +103,45 @@ private static final class RelativeSortedPaths {
103103 * @param list2 the second list.
104104 * @return whether the lists are equal.
105105 */
106- private static boolean equals (final List <Path > list1 , final List <Path > list2 ) {
106+ private static boolean equalsIgnoreFileSystem (final List <Path > list1 , final List <Path > list2 ) {
107107 if (list1 .size () != list2 .size ()) {
108108 return false ;
109109 }
110110 // compare both lists using iterators
111111 final Iterator <Path > iterator1 = list1 .iterator ();
112112 final Iterator <Path > iterator2 = list2 .iterator ();
113113 while (iterator1 .hasNext () && iterator2 .hasNext ()) {
114- final Path path1 = iterator1 .next ();
115- final Path path2 = iterator2 .next ();
116- final FileSystem fileSystem1 = path1 .getFileSystem ();
117- final FileSystem fileSystem2 = path2 .getFileSystem ();
118- if (fileSystem1 == fileSystem2 ) {
119- if (!path1 .equals (path2 )) {
120- return false ;
121- }
122- } else if (fileSystem1 .getSeparator ().equals (fileSystem2 .getSeparator ())) {
123- // Separators are the same, so we can use toString comparison
124- if (!path1 .toString ().equals (path2 .toString ())) {
125- return false ;
126- }
127- } else {
128- // Compare paths from different file systems component by component.
129- // Cant use toString() string comparison which may fail due to different path separators.
130- final Iterator <Path > path1Iterator = path1 .iterator ();
131- final Iterator <Path > path2Iterator = path2 .iterator ();
132- while (path1Iterator .hasNext () && path2Iterator .hasNext ()) {
133- if (!path1Iterator .next ().toString ().equals (path2Iterator .next ().toString ())) {
134- return false ;
135- }
136- }
137- // Check that both iterators are exhausted (paths have same number of components)
138- return !path1Iterator .hasNext () && !path2Iterator .hasNext ();
114+ if (!equalsIgnoreFileSystem (iterator1 .next (), iterator2 .next ())) {
115+ return false ;
139116 }
140117 }
141118 return true ;
142119 }
143120
121+ private static boolean equalsIgnoreFileSystem (final Path path1 , final Path path2 ) {
122+ final FileSystem fileSystem1 = path1 .getFileSystem ();
123+ final FileSystem fileSystem2 = path2 .getFileSystem ();
124+ if (fileSystem1 == fileSystem2 ) {
125+ return path1 .equals (path2 );
126+ }
127+ final String separator1 = fileSystem1 .getSeparator ();
128+ final String separator2 = fileSystem2 .getSeparator ();
129+ final String string1 = path1 .toString ();
130+ final String string2 = path2 .toString ();
131+ if (separator1 .equals (separator2 )) {
132+ // Separators are the same, so we can use toString comparison
133+ return string1 .equals (string2 );
134+ }
135+ // Compare paths from different file systems component by component.
136+ return extractKey (separator1 , string1 ).equals (extractKey (separator2 , string2 ));
137+ //return Arrays.equals(string1.split("\\" + separator1), string2.split("\\" + separator2));
138+ }
139+
140+ static String extractKey (final String separator , final String string ) {
141+ // Replace the file separator in a path string with a string that is not legal in a path on Windows, Linux, and macOS.
142+ return string .replaceAll ("\\ " + separator , ">" );
143+ }
144+
144145 final boolean equals ;
145146 // final List<Path> relativeDirList1; // might need later?
146147 // final List<Path> relativeDirList2; // might need later?
@@ -180,12 +181,12 @@ private RelativeSortedPaths(final Path dir1, final Path dir2, final int maxDepth
180181 } else {
181182 tmpRelativeDirList1 = visitor1 .relativizeDirectories (dir1 , true , null );
182183 tmpRelativeDirList2 = visitor2 .relativizeDirectories (dir2 , true , null );
183- if (!equals (tmpRelativeDirList1 , tmpRelativeDirList2 )) {
184+ if (!equalsIgnoreFileSystem (tmpRelativeDirList1 , tmpRelativeDirList2 )) {
184185 equals = false ;
185186 } else {
186187 tmpRelativeFileList1 = visitor1 .relativizeFiles (dir1 , true , null );
187188 tmpRelativeFileList2 = visitor2 .relativizeFiles (dir2 , true , null );
188- equals = equals (tmpRelativeFileList1 , tmpRelativeFileList2 );
189+ equals = equalsIgnoreFileSystem (tmpRelativeFileList1 , tmpRelativeFileList2 );
189190 }
190191 }
191192 }
@@ -198,40 +199,33 @@ private RelativeSortedPaths(final Path dir1, final Path dir2, final int maxDepth
198199 }
199200
200201 private static final OpenOption [] OPEN_OPTIONS_TRUNCATE = { StandardOpenOption .CREATE , StandardOpenOption .TRUNCATE_EXISTING };
201-
202202 private static final OpenOption [] OPEN_OPTIONS_APPEND = { StandardOpenOption .CREATE , StandardOpenOption .APPEND };
203-
204203 /**
205204 * Empty {@link CopyOption} array.
206205 *
207206 * @since 2.8.0
208207 */
209208 public static final CopyOption [] EMPTY_COPY_OPTIONS = {};
210-
211209 /**
212210 * Empty {@link DeleteOption} array.
213211 *
214212 * @since 2.8.0
215213 */
216214 public static final DeleteOption [] EMPTY_DELETE_OPTION_ARRAY = {};
217-
218215 /**
219216 * Empty {@link FileAttribute} array.
220217 *
221218 * @since 2.13.0
222219 */
223220 public static final FileAttribute <?>[] EMPTY_FILE_ATTRIBUTE_ARRAY = {};
224-
225221 /**
226222 * Empty {@link FileVisitOption} array.
227223 */
228224 public static final FileVisitOption [] EMPTY_FILE_VISIT_OPTION_ARRAY = {};
229-
230225 /**
231226 * Empty {@link LinkOption} array.
232227 */
233228 public static final LinkOption [] EMPTY_LINK_OPTION_ARRAY = {};
234-
235229 /**
236230 * {@link LinkOption} array for {@link LinkOption#NOFOLLOW_LINKS}.
237231 *
@@ -240,19 +234,16 @@ private RelativeSortedPaths(final Path dir1, final Path dir2, final int maxDepth
240234 */
241235 @ Deprecated
242236 public static final LinkOption [] NOFOLLOW_LINK_OPTION_ARRAY = { LinkOption .NOFOLLOW_LINKS };
243-
244237 /**
245238 * A LinkOption used to follow link in this class, the inverse of {@link LinkOption#NOFOLLOW_LINKS}.
246239 *
247240 * @since 2.12.0
248241 */
249242 static final LinkOption NULL_LINK_OPTION = null ;
250-
251243 /**
252244 * Empty {@link OpenOption} array.
253245 */
254246 public static final OpenOption [] EMPTY_OPEN_OPTION_ARRAY = {};
255-
256247 /**
257248 * Empty {@link Path} array.
258249 *
@@ -712,8 +703,9 @@ public static boolean directoryAndFileContentEquals(final Path path1, final Path
712703 final boolean sameFileSystem = isSameFileSystem (path1 , path2 );
713704 for (final Path path : fileList1 ) {
714705 final int binarySearch = sameFileSystem ? Collections .binarySearch (fileList2 , path )
715- : Collections .binarySearch (fileList2 , path , Comparator .comparing (Path ::toString ));
716- if (binarySearch <= -1 ) {
706+ : Collections .binarySearch (fileList2 , path ,
707+ Comparator .comparing (p -> RelativeSortedPaths .extractKey (p .getFileSystem ().getSeparator (), p .toString ())));
708+ if (binarySearch < 0 ) {
717709 throw new IllegalStateException ("Unexpected mismatch." );
718710 }
719711 if (sameFileSystem && !fileContentEquals (path1 .resolve (path ), path2 .resolve (path ), linkOptions , openOptions )) {
@@ -949,6 +941,7 @@ public static DosFileAttributeView getDosFileAttributeView(final Path path, fina
949941 * <p>
950942 * This method returns the textual part of the Path after the last period.
951943 * </p>
944+ *
952945 * <pre>
953946 * foo.txt --> "txt"
954947 * a/b/c.jpg --> "jpg"
@@ -971,8 +964,8 @@ public static String getExtension(final Path path) {
971964 /**
972965 * Gets the Path's file name and apply the given function if the file name is non-null.
973966 *
974- * @param <R> The function's result type.
975- * @param path the path to query.
967+ * @param <R> The function's result type.
968+ * @param path the path to query.
976969 * @param function function to apply to the file name.
977970 * @return the Path's file name as a string or null.
978971 * @see Path#getFileName()
@@ -1744,7 +1737,8 @@ public static BigInteger sizeOfDirectoryAsBigInteger(final Path directory) throw
17441737 return countDirectoryAsBigInteger (directory ).getByteCounter ().getBigInteger ();
17451738 }
17461739
1747- private static Path stripTrailingSeparator (final Path dir ) {
1740+ private static Path stripTrailingSeparator (final Path cdir ) {
1741+ final Path dir = cdir .normalize ();
17481742 final String separator = dir .getFileSystem ().getSeparator ();
17491743 final String fileName = dir .getFileName ().toString ();
17501744 return fileName .endsWith (separator ) ? dir .resolveSibling (fileName .substring (0 , fileName .length () - 1 )) : dir ;
@@ -1952,5 +1946,4 @@ public static Path writeString(final Path path, final CharSequence charSequence,
19521946 private PathUtils () {
19531947 // do not instantiate.
19541948 }
1955-
19561949}
0 commit comments