【发布时间】:2011-09-07 01:36:33
【问题描述】:
在java或groovy中将整个目录内容复制到另一个目录的方法?
【问题讨论】:
-
你想要一个命令行工具或代码?
标签: java grails file-io groovy
在java或groovy中将整个目录内容复制到另一个目录的方法?
【问题讨论】:
标签: java grails file-io 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()。也许这对其他人也有帮助。
Files.copy(Path, Path),但它似乎没有做同样的工作。
import org.apache.commons.io.FileUtils
以下是使用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,您可以leverage 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();
}
}
}
}
【讨论】:
这是我的一段 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)
}
}
【讨论】:
FileUtils.copyDirectory()好多少?
【讨论】:
Files.copy 支持目录,但它不会复制目录的内容。
随着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's answer 都不会复制目录属性(文件所有者、权限、修改时间等)。
https://stackoverflow.com/a/18691793/14731 提供了一个完整的 JDK7 解决方案,正是这样做的。
【讨论】:
关于Java,标准API中没有这样的方法。在 Java 7 中,java.nio.file.Files 类将提供 copy 便利方法。
参考文献
【讨论】:
Files.copy 不支持复制目录内容。
如果您愿意使用第 3 方库,请查看 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
您还可以提供文件过滤器来指定要复制的文件。这里还有更多例子:
【讨论】: