日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 7:复制和移动文件和目录

發布時間:2023/12/3 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 7:复制和移动文件和目录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章是我關于Java 7 java.nio.file軟件包的系列文章的繼續,這次涵蓋了文件的復制和移動以及完整的目錄樹。 如果您曾經對Java缺少copy和move方法感到沮喪,那么請繼續閱讀,以免麻煩。 涵蓋范圍中包括非常有用的Files.walkFileTree方法。 但是,在我們深入研究主要內容之前,需要一些背景信息。

路徑對象
路徑對象代表可能包含或不包含文件的目錄序列。 有三種方法構造Path對象:

  • FileSystems.getDefault()。getPath(字符串優先,字符串…更多)
  • Paths.get(String path,String…更多),調用FileSystems.getDefault()。getPath的便捷方法
  • 在java.io.File對象上調用toPath方法
  • 從現在開始,在所有示例中,我們將使用Paths.get方法。 以下是創建Path對象的一些示例:

    //Path string would be "/foo" Paths.get("/foo"); //Path string "/foo/bar" Paths.get("/foo","bar");

    要操作Path對象,可以使用Path.resolve和Path.relativize方法。 這是使用Path.resolve的示例:

    //This is our base path "/foo" Path base = Paths.get("/foo"); //filePath is "/foo/bar/file.txt" while base still "/foo" Path filePath = base.resolve("bar/file.txt");

    使用Path.resolve方法會將給定的String或Path對象附加到調用Path的末尾,除非給定的String或Path表示絕對路徑,否則將返回給定的路徑,例如:

    Path path = Paths.get("/foo"); //resolved Path string is "/usr/local" Path resolved = path.resolve("/usr/local");

    Path.relativize以相反的方式工作,返回一個新的相對路徑,如果根據調用的Path解析該路徑,則會得到相同的Path字符串。 這是一個例子:

    // base Path string "/usr"Path base = Paths.get("/usr");// foo Path string "/usr/foo"Path foo = base.resolve("foo");// bar Path string "/usr/foo/bar"Path bar = foo.resolve("bar");// relative Path string "foo/bar"Path relative = base.relativize(bar);

    Path類上另一個有用的方法是Path.getFileName,它返回此Path對象表示的最遠元素的名稱,該名稱是實際文件或目錄。 例如:

    //assume filePath constructed elsewhere as "/home/user/info.txt" //returns Path with path string "info.txt" filePath.getFileName()//now assume dirPath constructed elsewhere as "/home/user/Downloads" //returns Path with path string "Downloads" dirPath.getFileName()

    在下一節中,我們將研究如何將Path.resolve和Path.relativize與Files類一起使用來復制和移動文件。

    文件類

    Files類由使用Path對象處理文件和目錄的靜態方法組成。 盡管Files類中有50多種方法,但目前我們僅討論復制和移動方法。

    復制文件

    要將一個文件復制到另一個文件,您可以使用(對名稱有任何猜測嗎?)Files.copy方法– copy(路徑源,Path目標,CopyOption…選項)非常簡潔并且沒有匿名內部類,我們確定它是Java嗎? options參數是枚舉,用于指定應如何復制文件。 (實際上有2個不同的Enum類,LinkOption和StandardCopyOption,但是都實現CopyOption接口。)這是Files.copy的可用選項列表:

  • LinkOption.NOFOLLOW_LINKS
  • StandardCopyOption.COPY_ATTRIBUTES
  • StandardCopyOption.REPLACE_EXISTING
  • 還有一個StandardCopyOption.ATOMIC_MOVE枚舉,但是如果指定了此選項,則拋出UsupportedOperationException。 如果未指定任何選項,則默認為在目標文件存在或為符號鏈接的情況下引發錯誤。 如果路徑對象是目錄,那么將在目標位置中創建一個空目錄。 (請稍等!在引言中沒有說我們可以復制目錄的全部內容嗎?答案仍然是肯定的,而且即將到來!)這是使用Path使用Path對象將文件復制到另一個文件的示例.resolve和Path.relativize方法:

    Path sourcePath ...Path basePath ...Path targetPath ...Files.copy(sourcePath, targetPath.resolve(basePath.relativize(sourcePath));

    移動文件

    移動文件同樣簡單明了– move(路徑源,路徑目標,CopyOption…選項);

    可用的StandardCopyOptions枚舉是:

  • StandardCopyOption.REPLACE_EXISTING
  • StandardCopyOption.ATOMIC_MOVE
  • 如果使用StandardCopyOption.COPY_ATTRIBUTES調用Files.move,則會引發UnsupportedOperationException。 可以在空目錄上調用Files.move,或者如果它不需要移動目錄內容,例如重新命名,則調用將成功,否則將拋出IOException(我們將在下一節中看到如何移動非空目錄)。 如果目標文件已經存在,則默認為引發Exception。 如果源是符號鏈接,則鏈接本身將被移動,而不是鏈接的目標。 這是Files.move的示例,再次使用Path.relativize和Path.resolve方法:

    Path sourcePath ...Path basePath ...Path targetPath ...Files.move(sourcePath, targetPath.resolve(basePath.relativize(sourcePath));

    復制和移動目錄

    Files.walkFileTree是在Files類中找到的更有趣和有用的方法之一。 walkFileTree方法執行文件樹的深度優先遍歷。 有兩個簽名:

  • walkFileTree(路徑開始,設置選項,int maxDepth,FileVisitor訪問者)
  • walkFileTree(路徑開始,FileVisitor訪問者)
  • Files.walkFileTree的第二個選項使用EnumSet.noneOf(FileVisitOption.class)和Integer.MAX_VALUE調用第一個選項。 在撰寫本文時,只有一個文件訪問選項– FOLLOW_LINKS。 FileVisitor是一個接口,具有定義的四個方法:

  • preVisitDirectory(T dir,BasicFileAttributes attrs)在遍歷所有整數之前調用目錄。
  • visitFile(T file,BasicFileAttributes attrs)調用目錄中的文件。
  • postVisitDirectory(T dir,IOException exc)僅在遍歷所有文件和子目錄之后才調用。
  • visitFileFailed(T file,IOException exc)調用了無法訪問的文件
  • 所有方法都返回四個可能的FileVisitResult枚舉之一:

  • FileVistitResult.CONTINUE
  • FileVistitResult.SKIP_SIBLINGS(繼續而不遍歷目錄或文件的同級)
  • FileVistitResult.SKIP_SUBTREE(繼續而不遍歷目錄內容)
  • FileVistitResult.TERMINATE
  • 為了使生活更輕松,有一個默認的FileVisitor實現,即SimpleFileVisitor(validate參數不為null并返回FileVisitResult.CONTINUE),可以將其子類化,您可以覆蓋您需要使用的方法。 讓我們看一個用于復制整個目錄結構的基本示例。

    復制目錄樹示例

    讓我們看一下擴展用于復制目錄樹的SimpleFileVisitor的類(為清晰起見,省略了一些詳細信息):

    public class CopyDirVisitor extends SimpleFileVisitor<Path> {private Path fromPath;private Path toPath;private StandardCopyOption copyOption = StandardCopyOption.REPLACE_EXISTING;....@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {Path targetPath = toPath.resolve(fromPath.relativize(dir));if(!Files.exists(targetPath)){Files.createDirectory(targetPath);}return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption);return FileVisitResult.CONTINUE;} }

    在第9行中,將遍歷源文件“ fromPath”中的每個目錄,并在目標“ toPath”中創建每個目錄。 在這里,我們可以看到Path對象在處理目錄和文件方面的強大功能。 隨著代碼深入目錄結構,只需分別在fromPath和toPath對象上調用relativize和resolve即可構造正確的Path對象。 我們根本不需要知道我們在目錄樹中的位置,因此不需要繁瑣的StringBuilder操作即可創建正確的路徑。 在第17行,我們看到用于將文件從源目錄復制到目標目錄的Files.copy方法。 接下來是刪除整個目錄樹的簡單示例。

    刪除目錄樹示例

    在此示例中,SimpleFileVisitor已被子類化,用于刪除目錄結構:

    public class DeleteDirVisitor extends SimpleFileVisitor<Path> {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {if(exc == null){Files.delete(dir);return FileVisitResult.CONTINUE;}throw exc;} }

    如您所見,刪除是一個非常簡單的操作。 只需刪除找到的每個文件,然后在退出時刪除目錄即可。

    將Files.walkFileTree與Google Guava結合

    前兩個示例雖然有用,但非常“香草”。 讓我們看一下另外兩個示例,它們結合了Google Gauva Function和Predicate接口,它們更具創造力。

    public class FunctionVisitor extends SimpleFileVisitor<Path> {Function<Path,FileVisitResult> pathFunction;public FunctionVisitor(Function<Path, FileVisitResult> pathFunction) {this.pathFunction = pathFunction;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {return pathFunction.apply(file);} }

    在這個非常簡單的示例中,我們將SimpleFileVisitor子類化,以將Function對象作為構造函數參數,并且在遍歷目錄結構時,將該函數應用于每個文件。

    public class CopyPredicateVisitor extends SimpleFileVisitor<Path> {private Path fromPath;private Path toPath;private Predicate<Path> copyPredicate;public CopyPredicateVisitor(Path fromPath, Path toPath, Predicate<Path> copyPredicate) {this.fromPath = fromPath;this.toPath = toPath;this.copyPredicate = copyPredicate;}@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {if (copyPredicate.apply(dir)) {Path targetPath = toPath.resolve(fromPath.relativize(dir));if (!Files.exists(targetPath)) {Files.createDirectory(targetPath);}return FileVisitResult.CONTINUE;}return FileVisitResult.SKIP_SUBTREE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.copy(file, toPath.resolve(fromPath.relativize(file)));return FileVisitResult.CONTINUE;} }

    在此示例中,CopyPredicateVisitor接收一個Predicate對象,并且基于返回的布爾值,不會復制部分目錄結構。 我想指出的是,前面兩個示例(除了有用性之外)確實可以在本文后面的源代碼中進行單元測試。

    DirUtils

    在到目前為止所介紹的所有內容的基礎上,我無法抗拒創建實用程序類DirUtils的機會, 該類是使用以下提供以下方法的目錄的抽象:

    //deletes all files but leaves the directory tree in placeDirUtils.clean(Path sourcePath);//completely removes a directory treeDirUtils.delete(Path sourcePath);//replicates a directory treeDirUtils.copy(Path sourcePath, Path targetPath);//not a true move but performs a copy then a delete of a directory treeDirUtils.move(Path sourcePath, Path targetPath);//apply the function to all files visitedDirUtils.apply(Path sourcePath,Path targetPath, Function function);

    雖然我不愿意說它已經可以生產了,但是寫起來很有趣。

    結論

    這就包裝了java.nio.file包提供的新的復制和移動功能。 我個人認為這非常有用,并且可以減輕使用Java中文件的痛苦。 還有更多內容,涉及符號鏈接,流復制方法,DirectoryStreams等,因此請務必堅持。 謝謝你的時間。 一如既往地歡迎提出意見和建議。

    參考: Java 7的新增功能: JCG合作伙伴的 文件和目錄的復制和移動 ? 比爾·貝杰克(Bill Bejeck)在“ 編碼隨機思想”博客上。


    翻譯自: https://www.javacodegeeks.com/2012/02/java-7-copy-and-move-files-and.html

    總結

    以上是生活随笔為你收集整理的Java 7:复制和移动文件和目录的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。