2013-07-14 34 views
3

我看到很多examples使用Files.walkFileTree()將目錄及其內容從一個位置複製到另一個位置,但它們無法考慮該目錄的文件屬性和權限。意思是,他們只是調用Files.createDirectories()沒有任何屬性或權限。如何將目錄及其屬性/權限從一個位置複製到另一個位置?

如何使用Java7核心類將目錄(及其內容)從一個位置複製到另一個位置而不會丟失文件屬性或權限?

+0

另一個:http://stackoverflow.com/a/20085222/281545和香草一:http://docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java –

+0

@Mr_and_Mrs_D ,您引用的示例不會複製文件權限(僅限屬性)。他們也不復制目錄權限和屬性。 – Gili

回答

10

回答我的問題:

/** 
* 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; 
      } 
     }); 
} 

此代碼沒有被廣泛的測試,但它爲我工作。

+0

兩個問題:1.爲什麼不是香草一個:http://docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java 2.爲什麼不實施SimpleFileVisitor –

+0

這個設計也可以從中獲利一個接受Class

+0

@Mr_and_Mrs_D中擴展FileAttributeView(或AttributeView)>,「vanilla one」複製屬性而不是權限。你認爲哪條線路是這樣做的? – Gili

相關問題