Fix directory handling, add more content listing methods
This commit is contained in:
parent
a7c02cc9c2
commit
a392e8eb48
1 changed files with 157 additions and 3 deletions
|
@ -26,6 +26,7 @@ import de.staropensource.engine.base.utility.misc.Miscellaneous;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -34,6 +35,7 @@ import java.net.URI;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.nio.file.attribute.PosixFilePermissions;
|
import java.nio.file.attribute.PosixFilePermissions;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -410,7 +412,7 @@ public final class FileAccess {
|
||||||
* @throws IOException on an IO error
|
* @throws IOException on an IO error
|
||||||
* @since v1-alpha8
|
* @since v1-alpha8
|
||||||
*/
|
*/
|
||||||
public @NotNull String @NotNull [] listContents() throws UnsupportedOperationException, IOException {
|
public @NotNull String @NotNull [] list() throws UnsupportedOperationException, IOException {
|
||||||
if (getType() != Type.DIRECTORY)
|
if (getType() != Type.DIRECTORY)
|
||||||
throw new UnsupportedOperationException("The file '" + path + "' is not a directory");
|
throw new UnsupportedOperationException("The file '" + path + "' is not a directory");
|
||||||
|
|
||||||
|
@ -422,6 +424,58 @@ public final class FileAccess {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of all files
|
||||||
|
* in this directory.
|
||||||
|
*
|
||||||
|
* @return array of file names
|
||||||
|
* @throws UnsupportedOperationException if this file isn't a directory
|
||||||
|
* @throws IOException on an IO error
|
||||||
|
* @since v1-alpha8
|
||||||
|
*/
|
||||||
|
public @NotNull String @NotNull [] listFiles() throws UnsupportedOperationException, IOException {
|
||||||
|
if (getType() != Type.DIRECTORY)
|
||||||
|
throw new UnsupportedOperationException("The file '" + path + "' is not a directory");
|
||||||
|
|
||||||
|
String[] listArray = file.list();
|
||||||
|
List<@NotNull String> list = new ArrayList<>();
|
||||||
|
|
||||||
|
if (listArray == null)
|
||||||
|
throw new IOException("list is null (isn't a directory although it should be one)");
|
||||||
|
|
||||||
|
for (String item : listArray)
|
||||||
|
if (path.resolve(item).toFile().isFile())
|
||||||
|
list.add(item);
|
||||||
|
|
||||||
|
return list.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of all
|
||||||
|
* directories in this directory.
|
||||||
|
*
|
||||||
|
* @return array of directory names
|
||||||
|
* @throws UnsupportedOperationException if this file isn't a directory
|
||||||
|
* @throws IOException on an IO error
|
||||||
|
* @since v1-alpha8
|
||||||
|
*/
|
||||||
|
public @NotNull String @NotNull [] listDirectories() throws UnsupportedOperationException, IOException {
|
||||||
|
if (getType() != Type.DIRECTORY)
|
||||||
|
throw new UnsupportedOperationException("The file '" + path + "' is not a directory");
|
||||||
|
|
||||||
|
String[] listArray = file.list();
|
||||||
|
List<@NotNull String> list = new ArrayList<>();
|
||||||
|
|
||||||
|
if (listArray == null)
|
||||||
|
throw new IOException("list is null (isn't a directory although it should be one)");
|
||||||
|
|
||||||
|
for (String item : listArray)
|
||||||
|
if (path.resolve(item).toFile().isDirectory())
|
||||||
|
list.add(item);
|
||||||
|
|
||||||
|
return list.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the destination of the symbolic link.
|
* Returns the destination of the symbolic link.
|
||||||
*
|
*
|
||||||
|
@ -699,6 +753,7 @@ public final class FileAccess {
|
||||||
* @since v1-alpha9
|
* @since v1-alpha9
|
||||||
*/
|
*/
|
||||||
public @NotNull FileAccess move(@NotNull FileAccess destination) throws IOException {
|
public @NotNull FileAccess move(@NotNull FileAccess destination) throws IOException {
|
||||||
|
Logger.diag("Moving '" + path + "' to '" + destination.path + "'");
|
||||||
Files.move(path, destination.path, StandardCopyOption.REPLACE_EXISTING);
|
Files.move(path, destination.path, StandardCopyOption.REPLACE_EXISTING);
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +767,11 @@ public final class FileAccess {
|
||||||
* @since v1-alpha9
|
* @since v1-alpha9
|
||||||
*/
|
*/
|
||||||
public @NotNull FileAccess copy(@NotNull FileAccess destination) throws IOException {
|
public @NotNull FileAccess copy(@NotNull FileAccess destination) throws IOException {
|
||||||
Files.copy(path, destination.path, StandardCopyOption.REPLACE_EXISTING);
|
Logger.diag("Copying '" + path + "' to '" + destination.path + "'");
|
||||||
|
if (file.isDirectory())
|
||||||
|
Files.walkFileTree(path, new CopyDirectoryVisitor(path, destination.path));
|
||||||
|
else
|
||||||
|
Files.copy(path, destination.path, StandardCopyOption.REPLACE_EXISTING);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,11 +780,17 @@ public final class FileAccess {
|
||||||
* If it doesn't exist, nothing will be done.
|
* If it doesn't exist, nothing will be done.
|
||||||
*
|
*
|
||||||
* @return this instance
|
* @return this instance
|
||||||
|
* @throws IOException on an IO error
|
||||||
* @since v1-alpha8
|
* @since v1-alpha8
|
||||||
*/
|
*/
|
||||||
public @NotNull FileAccess delete() {
|
public @NotNull FileAccess delete() throws IOException {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
Logger.diag("Deleting '" + path + "'");
|
Logger.diag("Deleting '" + path + "'");
|
||||||
|
|
||||||
|
// Recursively delete if directory
|
||||||
|
if (getFile().isDirectory())
|
||||||
|
Files.walkFileTree(path, new DeleteDirectoryVisitor(path));
|
||||||
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
|
@ -1013,4 +1078,93 @@ public final class FileAccess {
|
||||||
*/
|
*/
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link FileVisitor} instance for
|
||||||
|
* copying directories recursively.
|
||||||
|
*
|
||||||
|
* @param source source to copy from
|
||||||
|
* @param destination destination to copy to
|
||||||
|
* @since v1-alpha9
|
||||||
|
*/
|
||||||
|
private record CopyDirectoryVisitor(@NotNull Path source, @NotNull Path destination) implements FileVisitor<@NotNull Path> {
|
||||||
|
/**
|
||||||
|
* Creates and initializes an
|
||||||
|
* instance of this class.
|
||||||
|
*
|
||||||
|
* @since v1-alpha9
|
||||||
|
*/
|
||||||
|
private CopyDirectoryVisitor {}
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult preVisitDirectory(Path path, @NotNull BasicFileAttributes attributes) throws IOException {
|
||||||
|
Files.createDirectories(destination.resolve(source.relativize(path)));
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult visitFile(Path path, @NotNull BasicFileAttributes attributes) throws IOException {
|
||||||
|
Files.copy(path, destination.resolve(source.relativize(path)));
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult visitFileFailed(Path path, @NotNull IOException exception) throws IOException {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult postVisitDirectory(Path path, @Nullable IOException exception) throws IOException {
|
||||||
|
if (exception != null)
|
||||||
|
throw exception;
|
||||||
|
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link FileVisitor} instance for
|
||||||
|
* delete directories recursively.
|
||||||
|
*
|
||||||
|
* @param directory directory to delete
|
||||||
|
* @since v1-alpha9
|
||||||
|
*/
|
||||||
|
private record DeleteDirectoryVisitor(@NotNull Path directory) implements FileVisitor<@NotNull Path> {
|
||||||
|
/**
|
||||||
|
* Creates and initializes an
|
||||||
|
* instance of this class.
|
||||||
|
*
|
||||||
|
* @since v1-alpha9
|
||||||
|
*/
|
||||||
|
private DeleteDirectoryVisitor {}
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult preVisitDirectory(Path path, @NotNull BasicFileAttributes attributes) {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult visitFile(Path path, @NotNull BasicFileAttributes attributes) throws IOException {
|
||||||
|
Files.delete(path);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult visitFileFailed(Path path, @NotNull IOException exception) throws IOException {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult postVisitDirectory(Path path, @Nullable IOException exception) throws IOException {
|
||||||
|
if (exception != null)
|
||||||
|
throw exception;
|
||||||
|
|
||||||
|
Files.delete(path);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue