33import java .io .File ;
44import java .io .IOException ;
55import java .nio .file .FileSystems ;
6+ import java .nio .file .FileVisitOption ;
7+ import java .nio .file .FileVisitResult ;
8+ import java .nio .file .FileVisitor ;
69import java .nio .file .Files ;
710import java .nio .file .Path ;
811import java .nio .file .PathMatcher ;
912import java .nio .file .Paths ;
10- import java .util .Comparator ;
13+ import java .nio .file .attribute .BasicFileAttributes ;
14+ import java .util .ArrayList ;
15+ import java .util .Collections ;
16+ import java .util .EnumSet ;
17+ import java .util .List ;
1118import java .util .Objects ;
12- import java .util .Optional ;
13- import java .util .stream .Stream ;
1419
1520/**
1621 * This utility class provides a {@link #getNextPath(Path, String, String) getNextPath} method to acquire the next file
@@ -151,8 +156,6 @@ private static Path getTargetPath() {
151156 * @throws IOException if an I/O error is thrown when accessing the starting file.
152157 */
153158 public static Path getNextPath (Path targetPath , String baseName , String extension ) throws IOException {
154- String newName ;
155-
156159 Objects .requireNonNull (targetPath , "[targetPath] must be non-null" );
157160 Objects .requireNonNull (baseName , "[baseName] must be non-null" );
158161 Objects .requireNonNull (extension , "[extension] must be non-null" );
@@ -168,41 +171,75 @@ public static Path getNextPath(Path targetPath, String baseName, String extensio
168171 throw new IllegalArgumentException ("[extension] must specify a non-empty string" );
169172 }
170173
171- PathMatcher pathMatcher = FileSystems .getDefault ().getPathMatcher ("regex:\\ Q" + baseName + "\\ E(-\\ d+)?\\ ." + extension );
174+ Visitor visitor = new Visitor (baseName , extension );
175+ Files .walkFileTree (targetPath , EnumSet .noneOf (FileVisitOption .class ), 1 , visitor );
172176
173- try (Stream <Path > stream = Files .walk (targetPath , 1 )) {
174- int base = baseName .length ();
175- int ext = extension .length () + 1 ;
176-
177- Optional <Integer > optional =
178- stream
179- .map (Path ::getFileName )
180- .filter (pathMatcher ::matches )
181- .map (String ::valueOf )
182- .map (s -> "0" + s .substring (base , s .length () - ext ))
183- .map (s -> s .replace ("0-" , "" ))
184- .map (Integer ::valueOf )
185- .map (i -> i + 1 )
186- .sorted (Comparator .reverseOrder ())
187- .findFirst ();
177+ return targetPath .resolve (visitor .getNewName ());
178+ }
179+
180+ /**
181+ * Get project base directory.
182+ *
183+ * @return project base directory
184+ */
185+ public static String getBaseDir () {
186+ Path currentRelativePath = Paths .get (System .getProperty ("user.dir" ));
187+ return currentRelativePath .toAbsolutePath ().toString ();
188+ }
189+
190+ private static class Visitor implements FileVisitor <Path > {
191+
192+ private String baseName ;
193+ private String extension ;
194+ private int base , ext ;
195+ private PathMatcher pathMatcher ;
196+ private List <Integer > intList = new ArrayList <>();
197+
198+ Visitor (String baseName , String extension ) {
199+ this .baseName = baseName ;
200+ this .extension = extension ;
201+ this .base = baseName .length ();
202+ this .ext = extension .length () + 1 ;
203+ this .pathMatcher = FileSystems .getDefault ().getPathMatcher ("regex:\\ Q" + baseName + "\\ E(-\\ d+)?\\ ." + extension );
204+ }
205+
206+ @ Override
207+ public FileVisitResult preVisitDirectory (Path dir , BasicFileAttributes attrs ) throws IOException {
208+ return FileVisitResult .CONTINUE ;
209+ }
210+
211+ @ Override
212+ public FileVisitResult visitFile (Path file , BasicFileAttributes attrs ) throws IOException {
213+ if (attrs .isRegularFile () && pathMatcher .matches (file .getFileName ())) {
214+ String name = file .getFileName ().toString ();
215+ String iStr = "0" + name .substring (base , name .length () - ext );
216+ iStr = iStr .replace ("0-" , "" );
217+ intList .add (Integer .valueOf (iStr ) + 1 );
218+ }
219+ return FileVisitResult .CONTINUE ;
220+ }
221+
222+ @ Override
223+ public FileVisitResult visitFileFailed (Path file , IOException exc ) throws IOException {
224+ return FileVisitResult .CONTINUE ;
225+ }
226+
227+ @ Override
228+ public FileVisitResult postVisitDirectory (Path dir , IOException exc ) throws IOException {
229+ return FileVisitResult .CONTINUE ;
230+ }
231+
232+ public String getNewName () {
233+ String newName ;
188234
189- if (optional .isPresent ()) {
190- newName = baseName + "-" + optional .get () + "." + extension ;
191- } else {
235+ if (intList .isEmpty ()) {
192236 newName = baseName + "." + extension ;
237+ } else {
238+ Collections .sort (intList , Collections .reverseOrder ());
239+ newName = baseName + "-" + intList .get (0 ) + "." + extension ;
193240 }
241+
242+ return newName ;
194243 }
195-
196- return targetPath .resolve (newName );
197244 }
198-
199- /**
200- * Get project base directory.
201- *
202- * @return project base directory
203- */
204- public static String getBaseDir () {
205- Path currentRelativePath = Paths .get (System .getProperty ("user.dir" ));
206- return currentRelativePath .toAbsolutePath ().toString ();
207- }
208245}
0 commit comments