如何将具有属性/权限的目录从一个位置复制到另一个位置?
Posted
技术标签:
【中文标题】如何将具有属性/权限的目录从一个位置复制到另一个位置?【英文标题】:How to copy a directory with its attributes/permissions from one location to another? 【发布时间】:2013-07-12 13:51:48 【问题描述】:我看到很多examples 使用Files.walkFileTree()
将目录及其内容从一个位置复制到另一个位置,但他们没有考虑到目录的文件属性和权限。意思是,他们只是调用Files.createDirectories()
,没有任何属性或权限。
如何使用 Java7 核心类将目录(及其内容)从一个位置复制到另一个位置而不丢失文件属性或权限?
【问题讨论】:
另一个:***.com/a/20085222/281545 和香草一个:docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java @Mr_and_Mrs_D,您引用的示例不复制文件权限(仅属性)。它们也不复制目录权限和属性。 【参考方案1】:回答我自己的问题:
/**
* Copies a directory.
* <p>
* NOTE: This method is not thread-safe.
* <p>
*
* @param source
* the directory to copy from
* @param target
* the directory to copy into
* @throws IOException
* if an I/O error occurs
*/
private static void copyDirectory(final Path source, final Path target)
throws IOException
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
Integer.MAX_VALUE, new FileVisitor<Path>()
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes sourceBasic) throws IOException
Path targetDir = Files.createDirectories(target
.resolve(source.relativize(dir)));
AclFileAttributeView acl = Files.getFileAttributeView(dir,
AclFileAttributeView.class);
if (acl != null)
Files.getFileAttributeView(targetDir,
AclFileAttributeView.class).setAcl(acl.getAcl());
DosFileAttributeView dosAttrs = Files.getFileAttributeView(
dir, DosFileAttributeView.class);
if (dosAttrs != null)
DosFileAttributes sourceDosAttrs = dosAttrs
.readAttributes();
DosFileAttributeView targetDosAttrs = Files
.getFileAttributeView(targetDir,
DosFileAttributeView.class);
targetDosAttrs.setArchive(sourceDosAttrs.isArchive());
targetDosAttrs.setHidden(sourceDosAttrs.isHidden());
targetDosAttrs.setReadOnly(sourceDosAttrs.isReadOnly());
targetDosAttrs.setSystem(sourceDosAttrs.isSystem());
FileOwnerAttributeView ownerAttrs = Files
.getFileAttributeView(dir, FileOwnerAttributeView.class);
if (ownerAttrs != null)
FileOwnerAttributeView targetOwner = Files
.getFileAttributeView(targetDir,
FileOwnerAttributeView.class);
targetOwner.setOwner(ownerAttrs.getOwner());
PosixFileAttributeView posixAttrs = Files
.getFileAttributeView(dir, PosixFileAttributeView.class);
if (posixAttrs != null)
PosixFileAttributes sourcePosix = posixAttrs
.readAttributes();
PosixFileAttributeView targetPosix = Files
.getFileAttributeView(targetDir,
PosixFileAttributeView.class);
targetPosix.setPermissions(sourcePosix.permissions());
targetPosix.setGroup(sourcePosix.group());
UserDefinedFileAttributeView userAttrs = Files
.getFileAttributeView(dir,
UserDefinedFileAttributeView.class);
if (userAttrs != null)
UserDefinedFileAttributeView targetUser = Files
.getFileAttributeView(targetDir,
UserDefinedFileAttributeView.class);
for (String key : userAttrs.list())
ByteBuffer buffer = ByteBuffer.allocate(userAttrs
.size(key));
userAttrs.read(key, buffer);
buffer.flip();
targetUser.write(key, buffer);
// Must be done last, otherwise last-modified time may be
// wrong
BasicFileAttributeView targetBasic = Files
.getFileAttributeView(targetDir,
BasicFileAttributeView.class);
targetBasic.setTimes(sourceBasic.lastModifiedTime(),
sourceBasic.lastAccessTime(),
sourceBasic.creationTime());
return FileVisitResult.CONTINUE;
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException
Files.copy(file, target.resolve(source.relativize(file)),
StandardCopyOption.COPY_ATTRIBUTES);
return FileVisitResult.CONTINUE;
@Override
public FileVisitResult
visitFileFailed(Path file, IOException e)
throws IOException
throw e;
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException e) throws IOException
if (e != null) throw e;
return FileVisitResult.CONTINUE;
);
此代码尚未经过广泛测试,但对我有用。
【讨论】:
两个问题:1. 为什么不是原版的:docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java 2. 为什么不是 SimpleFileVisitor 的实现 该设计还可以从一个枚举中受益,该枚举将在其构造函数中接受 ClassClass<T extends FileAttributeView>
不是enum
,也不清楚你指的是什么构造函数。
回复:枚举:dropbox.com/s/ngrwqnhzx7o7iqu/CopyDirectory.java。回复:香草一号 - 只是在问,我现在明白了。请注意,我将匿名类更改为嵌套并使其实现 SimpleFileVisitor(如 visitFileFailed 和 postVisitDirectory)在您的匿名实现中具有默认行为以上是关于如何将具有属性/权限的目录从一个位置复制到另一个位置?的主要内容,如果未能解决你的问题,请参考以下文章