Created
January 27, 2021 04:20
-
-
Save EvgeniGordeev/90b04409acedb6627751f96f6743253d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; | |
import java.io.IOException; | |
import java.net.MalformedURLException; | |
import java.net.URI; | |
import java.net.URISyntaxException; | |
import java.net.URL; | |
import java.nio.file.FileSystem; | |
import java.nio.file.FileSystems; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.nio.file.ProviderMismatchException; | |
import java.util.Collections; | |
import java.util.jar.JarEntry; | |
import java.util.jar.JarFile; | |
import java.util.stream.Stream; | |
/** | |
* Recursive copy of directory from a folder on the file system or inside a jar to another folder. | |
*/ | |
public class Copy { | |
public static void main(String[] args) throws MalformedURLException { | |
if (args == null || args.length < 2) { | |
System.out.println("Usage: CopyDir <dir_from> <dir_to>, dir_from may start with file: or jar:file:"); | |
return; | |
} | |
String from = args[0]; | |
if (!from.startsWith("file:") || !from.startsWith("jar:")) { | |
from = "file:" + from; | |
} | |
cp(new URL(from), Paths.get(args[1])); | |
} | |
@FunctionalInterface | |
interface TriFunction<A, B, C, R> { | |
R apply(A a, B b, C c); | |
} | |
/** | |
* Copy a file or a directory recursively from the file system or within a jar file. | |
* | |
* @param fromUrl URL to a directory or file to copy | |
* @param toPath where copy the target to | |
* @return true if operation successful | |
*/ | |
public static boolean cp(URL fromUrl, Path toPath) { | |
if (fromUrl == null) { | |
return false; | |
} | |
try { | |
final Path from; | |
TriFunction<Path, Path, Path, Path> getDest; | |
URI fromUri = fromUrl.toURI(); | |
switch (fromUrl.getProtocol()) { | |
case "file": | |
Path path = Paths.get(fromUri); | |
if (!Files.exists(path)) { | |
return false; | |
} | |
from = path.toRealPath(); | |
getDest = (source, toDir, fromDir) -> toDir.resolve(fromDir.relativize(source)); | |
break; | |
case "jar": | |
final FileSystem fileSystem = FileSystems.newFileSystem(fromUri, Collections.emptyMap()); | |
final String wholePath = fromUri.toString(); | |
final String jarFile = fileSystem.toString(); | |
if (!Files.exists(Paths.get(jarFile))) { | |
return false; | |
} | |
String jarName = Paths.get(fileSystem.toString()).getFileName().toString(); | |
String pathInJar = wholePath.substring(wholePath.indexOf(jarName + "!") + jarName.length() + 1 /* taking ! into account */); | |
JarFile jar = new JarFile(jarFile); | |
JarEntry entry = jar.getJarEntry(pathInJar.startsWith("/") ? pathInJar.substring(1) : pathInJar); | |
if (entry == null) { | |
return false; | |
} | |
from = fileSystem.getPath(pathInJar); | |
getDest = (source, toDir, fromDir) -> toDir.resolve(fromDir.relativize(fileSystem.getPath(source.toString())).toString()); | |
break; | |
default: | |
System.out.printf("Unknown file system - %s%n", fromUrl.getProtocol()); | |
return false; | |
} | |
// mkdir -p | |
if (!Files.exists(toPath)) { | |
Files.createDirectories(toPath); | |
} | |
Path to = toPath.toRealPath(); | |
System.out.printf("Copying %s to %s%n", fromUrl, to); | |
try (Stream<Path> stream = Files.walk(from)) { | |
stream.forEach(source -> copy(source, getDest.apply(source, to, from))); | |
} | |
} catch (IOException | URISyntaxException | ProviderMismatchException e) { | |
System.out.println(e.getMessage()); | |
return false; | |
} | |
return true; | |
} | |
private static void copy(Path source, Path dest) { | |
try { | |
Files.copy(source, dest, REPLACE_EXISTING); | |
} catch (IOException e) { | |
throw new RuntimeException("Couldn't copy", e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment