177 lines
7.5 KiB
Java
177 lines
7.5 KiB
Java
package io.gitlab.jfronny.commons.io;
|
|
|
|
import io.gitlab.jfronny.commons.serialize.Serializer;
|
|
import io.gitlab.jfronny.commons.throwable.ThrowingConsumer;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.io.*;
|
|
import java.lang.reflect.Type;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.nio.file.*;
|
|
import java.nio.file.attribute.BasicFileAttributes;
|
|
import java.util.*;
|
|
import java.util.function.Predicate;
|
|
import java.util.stream.Stream;
|
|
|
|
public class JFiles {
|
|
public static void clearDirectory(Path directory) throws IOException {
|
|
clearDirectory(directory, p -> true);
|
|
}
|
|
|
|
public static void clearDirectory(Path directory, Predicate<Path> shouldDelete) throws IOException {
|
|
if (!Files.exists(directory)) return;
|
|
try {
|
|
listTo(directory, p -> {
|
|
if (Files.isDirectory(p)) {
|
|
try {
|
|
if (shouldDelete.test(p))
|
|
deleteRecursive(p, shouldDelete);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
if (shouldDelete.test(p))
|
|
Files.delete(p);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
});
|
|
} catch (Throwable t) {
|
|
throw new IOException("Could not clear directory", t);
|
|
}
|
|
}
|
|
|
|
public static void deleteRecursive(Path path) throws IOException {
|
|
deleteRecursive(path, p -> true);
|
|
}
|
|
|
|
public static void deleteRecursive(Path path, Predicate<Path> shouldDelete) throws IOException {
|
|
if (Files.isDirectory(path)) {
|
|
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
|
@Override
|
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
FileVisitResult fv = super.visitFile(file, attrs);
|
|
if (fv != FileVisitResult.CONTINUE) return fv;
|
|
if (shouldDelete.test(file))
|
|
Files.delete(file);
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
|
|
@Override
|
|
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
|
FileVisitResult fv = super.postVisitDirectory(dir, exc);
|
|
if (fv != FileVisitResult.CONTINUE) return fv;
|
|
if (shouldDelete.test(dir) && list(dir).isEmpty()) {
|
|
Files.delete(dir);
|
|
}
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
});
|
|
}
|
|
else Files.delete(path);
|
|
}
|
|
|
|
@Deprecated
|
|
public static void copyContent(Path source, Path destination) throws IOException {
|
|
copyRecursive(source, destination);
|
|
}
|
|
@Deprecated
|
|
public static void copyContent(Path source, Path target, CopyOption... copyOptions) throws IOException {
|
|
copyRecursive(source, target, copyOptions);
|
|
}
|
|
|
|
/**
|
|
* If the source is a file, copy it to the target. If it is a directory, create the target directory if it doesn't exist and copy the source directories content there
|
|
* @param source The path to copy from
|
|
* @param destination The path to copy to
|
|
* @throws IOException Something went wrong
|
|
*/
|
|
public static void copyRecursive(Path source, Path destination) throws IOException {
|
|
copyRecursive(source, destination, StandardCopyOption.COPY_ATTRIBUTES);
|
|
}
|
|
|
|
/**
|
|
* If the source is a file, copy it to the destination. If it is a directory, create the destination directory if it doesn't exist and copy the source directories' content there
|
|
* @param source The path to copy from
|
|
* @param destination The path to copy to
|
|
* @param copyOptions Copy options to use
|
|
* @throws IOException Something went wrong
|
|
*/
|
|
public static void copyRecursive(Path source, Path destination, CopyOption... copyOptions) throws IOException {
|
|
boolean replaceExisting = Arrays.asList(copyOptions).contains(StandardCopyOption.REPLACE_EXISTING);
|
|
if (Files.isDirectory(source)) {
|
|
Files.createDirectories(destination);
|
|
listTo(source, sourceResolved -> {
|
|
Path targetResolved = destination.resolve(sourceResolved.getFileName().toString());
|
|
if (Files.exists(destination)) {
|
|
if (!replaceExisting) return;
|
|
if (!Files.isDirectory(sourceResolved)) Files.delete(destination);
|
|
}
|
|
copyRecursive(sourceResolved, targetResolved, copyOptions);
|
|
});
|
|
} else if (Files.exists(source)) {
|
|
if (destination.getParent() != null) Files.createDirectories(destination.getParent());
|
|
if (!Files.exists(destination) || replaceExisting) Files.copy(source, destination, copyOptions);
|
|
} else throw new FileNotFoundException(source.toString());
|
|
}
|
|
|
|
public static List<Path> list(Path directory) throws IOException {
|
|
try (Stream<Path> sp = Files.list(directory)) {
|
|
return sp.toList();
|
|
}
|
|
}
|
|
|
|
public static List<Path> list(Path directory, Predicate<Path> entryPredicate) throws IOException {
|
|
try (Stream<Path> sp = Files.list(directory); Stream<Path> fi = sp.filter(entryPredicate)) {
|
|
return fi.toList();
|
|
}
|
|
}
|
|
|
|
public static String[] listNames(Path directory) throws IOException {
|
|
try (Stream<Path> sp = Files.list(directory)) {
|
|
return sp
|
|
.map(p -> Files.isDirectory(p) ? p.getFileName().toString() + "/" : p.getFileName().toString())
|
|
.toArray(String[]::new);
|
|
}
|
|
}
|
|
|
|
public static <TEx extends Exception> void listTo(Path directory, ThrowingConsumer<Path, TEx> consumer) throws IOException, TEx {
|
|
try (Stream<Path> sp = Files.list(directory)) {
|
|
for (Path path : sp.toList()) consumer.accept(path);
|
|
}
|
|
}
|
|
|
|
public static <T> T readObject(Path file, Type type) throws IOException {
|
|
try (BufferedReader br = Files.newBufferedReader(file)) {
|
|
return Serializer.getInstance().deserialize(br, type);
|
|
}
|
|
}
|
|
|
|
public static <T> T readObject(Path file, Class<T> type) throws IOException {
|
|
try (BufferedReader br = Files.newBufferedReader(file)) {
|
|
return Serializer.getInstance().deserialize(br, type);
|
|
}
|
|
}
|
|
|
|
public static void writeObject(Path file, Object object) throws IOException {
|
|
try (BufferedWriter bw = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
|
Serializer.getInstance().serialize(object, bw);
|
|
}
|
|
}
|
|
|
|
private static final Map<Path, MultiAccessFileSystem> zipFsCache = new HashMap<>();
|
|
public static FileSystem openZipFile(Path zip, boolean create, @Nullable ClassLoader classLoader) throws IOException, URISyntaxException {
|
|
synchronized (zipFsCache) {
|
|
if (!zipFsCache.containsKey(zip) || zipFsCache.get(zip).isClosed()) {
|
|
URI fileUri = zip.toUri();
|
|
zipFsCache.put(zip, MultiAccessFileSystem.create(new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null), create ? Map.of("create", "true") : Map.of(), classLoader));
|
|
}
|
|
return zipFsCache.get(zip).createLens();
|
|
}
|
|
}
|
|
}
|