如何在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();
}
FileUtils.copyDirectoryStructure()
。也许这对其他人也有帮助。 - Ethan LeroyFiles.copy(Path, Path)
,但似乎并没有完成相同的工作。 - herauimport org.apache.commons.io.FileUtils
- Jean Bob以下是使用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发行版的一部分,也是自动导入列表中的一项,这意味着它对于任何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();
}
}
}
}
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)
}
}
FileUtils.copyDirectory()
更好在哪里? - doelleriFiles.copy
支持目录,但它不会复制目录中的内容。 - Max随着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();
}
}
}
无论是FileUtils.copyDirectory()还是Archimedes的答案都不会复制目录属性(文件所有者、权限、修改时间等)。
https://dev59.com/uXTYa4cB1Zd3GeqPu3EB#18691793提供了一个完整的JDK7解决方案,可以精确地实现此功能。
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
您还可以提供一个文件过滤器来指定要复制哪些文件。这里有更多的示例:
Files.copy
不支持复制目录内容。 - Max