ディレクトリの内容全体をJavaまたはgroovyの別のディレクトリにコピーする方法
ディレクトリ全体をファイルの日付を保存した新しい場所にコピーします。このメソッドは、指定されたディレクトリとそのすべての子ディレクトリとファイルを指定された宛先にコピーします。宛先は、ディレクトリの新しい場所と名前です。
宛先ディレクトリが存在しない場合は作成されます。宛先ディレクトリが存在した場合、このメソッドはソースを宛先にマージし、ソースを優先します。
そうするために、ここにコード例があります
String source = "C:/your/source";
File srcDir = new File(source);
String destination = "C:/your/destination";
File destDir = new File(destination);
try {
FileUtils.copyDirectory(srcDir, destDir);
} catch (IOException e) {
e.printStackTrace();
}
以下は、JDK7の使用例です。
public class CopyFileVisitor extends SimpleFileVisitor<Path> {
private final Path targetPath;
private Path sourcePath = null;
public CopyFileVisitor(Path targetPath) {
this.targetPath = targetPath;
}
@Override
public FileVisitResult preVisitDirectory(final Path dir,
final BasicFileAttributes attrs) throws IOException {
if (sourcePath == null) {
sourcePath = dir;
} else {
Files.createDirectories(targetPath.resolve(sourcePath
.relativize(dir)));
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path file,
final BasicFileAttributes attrs) throws IOException {
Files.copy(file,
targetPath.resolve(sourcePath.relativize(file)));
return FileVisitResult.CONTINUE;
}
}
訪問者を使用するには、次の操作を行います
Files.walkFileTree(sourcePath, new CopyFileVisitor(targetPath));
むしろすべてをインラインにしたい場合(頻繁に使用するとあまり効率的ではありませんが、迅速に使用できます)
final Path targetPath = // target
final Path sourcePath = // source
Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(final Path dir,
final BasicFileAttributes attrs) throws IOException {
Files.createDirectories(targetPath.resolve(sourcePath
.relativize(dir)));
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path file,
final BasicFileAttributes attrs) throws IOException {
Files.copy(file,
targetPath.resolve(sourcePath.relativize(file)));
return FileVisitResult.CONTINUE;
}
});
Groovyでは、 Antを活用 を実行できます。
new AntBuilder().copy( todir:'/path/to/destination/folder' ) {
fileset( dir:'/path/to/src/folder' )
}
AntBuilderはディストリビューションと自動インポートリストの一部であり、すべてのgroovyコードで直接利用できます。
public static void copyFolder(File source, File destination)
{
if (source.isDirectory())
{
if (!destination.exists())
{
destination.mkdirs();
}
String files[] = source.list();
for (String file : files)
{
File srcFile = new File(source, file);
File destFile = new File(destination, file);
copyFolder(srcFile, destFile);
}
}
else
{
InputStream in = null;
OutputStream out = null;
try
{
in = new FileInputStream(source);
out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0)
{
out.write(buffer, 0, length);
}
}
catch (Exception e)
{
try
{
in.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
try
{
out.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
}
FileUtils.copyDirectory() または Archimedesの回答 コピーディレクトリ属性(ファイル所有者、権限、変更時間など)のいずれでもありません。
https://stackoverflow.com/a/18691793/14731 は、まさにそれを行う完全なJDK7ソリューションを提供します。
これがそのための私のGroovyコードです。テスト済み。
private static void copyLargeDir(File dirFrom, File dirTo){
// creation the target dir
if (!dirTo.exists()){
dirTo.mkdir();
}
// copying the daughter files
dirFrom.eachFile(FILES){File source ->
File target = new File(dirTo,source.getName());
target.bytes = source.bytes;
}
// copying the daughter dirs - recursion
dirFrom.eachFile(DIRECTORIES){File source ->
File target = new File(dirTo,source.getName());
copyLargeDir(source, target)
}
}
Java NIOの登場により、以下も可能な解決策です。
Java 9の場合:
private static void copyDir(String src, String dest, boolean overwrite) {
try {
Files.walk(Paths.get(src)).forEach(a -> {
Path b = Paths.get(dest, a.toString().substring(src.length()));
try {
if (!a.toString().equals(src))
Files.copy(a, b, overwrite ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{});
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
//permission issue
e.printStackTrace();
}
}
Java 7の場合:
import Java.io.IOException;
import Java.nio.file.FileAlreadyExistsException;
import Java.nio.file.Files;
import Java.nio.file.Path;
import Java.nio.file.Paths;
import Java.util.function.Consumer;
import Java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
Path sourceParentFolder = Paths.get("/sourceParent");
Path destinationParentFolder = Paths.get("/destination/");
try {
Stream<Path> allFilesPathStream = Files.walk(sourceParentFolder);
Consumer<? super Path> action = new Consumer<Path>(){
@Override
public void accept(Path t) {
try {
String destinationPath = t.toString().replaceAll(sourceParentFolder.toString(), destinationParentFolder.toString());
Files.copy(t, Paths.get(destinationPath));
}
catch(FileAlreadyExistsException e){
//TODO do acc to business needs
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
allFilesPathStream.forEach(action );
} catch(FileAlreadyExistsException e) {
//file already exists and unable to copy
} catch (IOException e) {
//permission issue
e.printStackTrace();
}
}
}
サードパーティのライブラリを使用する場合は、 javaxt-core を確認してください。 javaxt.io.Directoryクラスを使用して、次のようにディレクトリをコピーできます。
javaxt.io.Directory input = new javaxt.io.Directory("/source");
javaxt.io.Directory output = new javaxt.io.Directory("/destination");
input.copyTo(output, true); //true to overwrite any existing files
ファイルフィルターを提供して、コピーするファイルを指定することもできます。ここに他の例があります:
Javaに関しては、標準APIにはそのようなメソッドはありません。 Java 7では、Java.nio.file.Files
クラスが copy 便利なメソッドを提供します。
参考文献