將檔案或資源集合複製到新的檔案或目錄。預設情況下,檔案只會在來源檔案比目標檔案新,或當目標檔案不存在時才會複製 - 請參閱 granularity 屬性以了解 Ant 中較新的定義。不過,您可以使用 overwrite
屬性明確覆寫檔案。
資源集合 用於選取要複製的檔案群組。若要使用資源集合,必須設定 todir 屬性。請注意,有些資源(例如 檔案 資源)會傳回絕對路徑作為名稱,而未透過嵌套映射器(或 flatten 屬性)使用它們的結果可能與您的預期不同。
請注意:如果您在複製作業中使用篩選器,則應將複製限制為文字檔案。複製作業會損毀二進位檔案。這適用於由 filter 工作隱含定義或明確提供給複製作業的 filtersets 的篩選器。請參閱 編碼註解。
屬性 | 說明 | 必要 |
---|---|---|
檔案 | 要複製的檔案。 | 是,除非使用嵌套資源集合元素 |
preservelastmodified | 讓複製檔案的最後修改時間與原始來源檔案相同。 | 否;預設為 false |
tofile | 要複製到的檔案。在 Apache Ant 1.8.2 之前,tofile 屬性僅支援從中複製的 檔案資源。 | 使用 file 屬性時,可以使用 tofile 或 todir。 使用嵌套資源集合元素時,如果包含的資源數量大於 1,或如果在 <fileset> 中僅指定 dir 屬性,或如果也指定 file 屬性,則僅允許 todir。 |
todir | 要複製到的目錄。 | |
overwrite | 即使目標檔案較新,也覆寫現有檔案。 | 否;預設為 false |
force | 覆寫唯讀目標檔案。自 Ant 1.8.2 起 | 否;預設為 false |
過濾 | 指出在複製期間是否應使用 全域建置檔案過濾器 進行標記過濾。注意:即使未指定此屬性,或其值為 false、 no或 off,仍將始終使用巢狀 <filterset> 元素。 |
否;預設為 false |
扁平化 | 忽略來源檔案的目錄結構,並將所有檔案複製到 todir 屬性指定的目錄中。請注意,您可以使用 扁平化對應器 來達成相同的目的。 | 否;預設為 false |
includeEmptyDirs | 複製 FileSet 中包含的任何空目錄。 | 否;預設為 true |
failonerror | 如果為 false,則在複製檔案不存在或其中一個巢狀檔案集指向不存在的目錄,或複製時發生錯誤時,記錄警告訊息,但不要停止建置。 |
否;預設為 true |
quiet | 如果為 true且 failonerror 為 false,則在複製檔案不存在或其中一個巢狀檔案集指向不存在的目錄,或複製時發生錯誤時,不要記錄警告訊息。自 Ant 1.8.3 起。 |
否;預設為 false |
verbose | 記錄正在複製的檔案。 | 否;預設為 false |
編碼 | 過濾複製檔案時假設的編碼。自 Ant 1.5 起。 | 否;預設為預設 JVM 字元編碼 |
outputencoding | 寫入檔案時使用的編碼。自 Ant 1.6 起。 | 否;預設為已設定的 encoding,否則為預設 JVM 字元編碼 |
enablemultiplemappings | 如果為 true,則任務將處理給定來源路徑的所有對應。如果為 false,則任務將只處理第一個檔案或目錄。此屬性僅在有 mapper 子元素時才相關。自 Ant 1.6 起。 |
否;預設為 false |
粒度 | 在決定檔案是否過期之前給予的寬限毫秒數。這是必要的,因為並非每個檔案系統都支援追蹤到毫秒級別的最後修改時間。如果來源檔案和目標檔案位於時鐘不同步的不同機器上,這也可能很有用。自 Ant 1.6.2 起。 | 否;預設為 1 秒,或在 DOS 系統上為 2 秒 |
資源收集 用於選取要複製的檔案群組。若要使用資源收集,必須設定 todir 屬性。
在 Ant 1.7 之前,只支援 <fileset>
作為巢狀元素。
你可以使用巢狀 轉換器 元素來定義檔案名稱轉換。<copy>
使用的預設轉換器為 身分轉換器。
自 Ant 1.6.3 起,你可以使用檔案名稱轉換器類型來取代轉換器元素。
請注意,傳遞給轉換器的來源名稱取決於你使用的資源集合。如果你使用 <fileset>
或任何其他提供基本目錄的集合,傳遞給轉換器的名稱將會是相對於基本目錄的相對檔案名稱。在任何其他情況下,將會使用來源的絕對檔案名稱。
過濾器組 用於取代複製檔案中的代碼。若要使用過濾器組,請使用巢狀 <filterset>
元素。
可以同時使用多個過濾器組。
複製任務支援巢狀 過濾器鏈。
如果在同一個 <copy>
任務內使用 <filterset>
和 <filterchain>
元素,所有 <filterchain>
元素會先處理,接著才是 <filterset>
元素。
複製單一檔案
<copy file="myfile.txt" tofile="mycopy.txt"/>
複製單一檔案到目錄
<copy file="myfile.txt" todir="../some/other/dir"/>
複製目錄到另一個目錄
<copy todir="../new/dir"> <fileset dir="src_dir"/> </copy>
複製一組檔案到目錄
<copy todir="../dest/dir"> <fileset dir="src_dir"> <exclude name="**/*.java"/> </fileset> </copy> <copy todir="../dest/dir"> <fileset dir="src_dir" excludes="**/*.java"/> </copy>
複製一組檔案到目錄,動態附加 .bak 到檔案名稱
<copy todir="../backup/dir"> <fileset dir="src_dir"/> <globmapper from="*" to="*.bak"/> </copy>
複製一組檔案到目錄,將所有檔案中的 @TITLE@
取代為 Foo Bar。
<copy todir="../backup/dir"> <fileset dir="src_dir"/> <filterset> <filter token="TITLE" value="Foo Bar"/> </filterset> </copy>
將目前 CLASSPATH
設定中的所有項目收集到目標目錄,並壓平目錄結構。
<copy todir="dest" flatten="true"> <path> <pathelement path="${java.class.path}"/> </path> </copy>
將一些資源複製到指定目錄。
<copy todir="dest" flatten="true"> <resources> <file file="src_dir/file1.txt"/> <url url="https://ant.dev.org.tw/index.html"/> </resources> </copy>
如果上述範例沒有使用 flatten 屬性,<file>
資源會將其完整路徑傳回作為來源和目標名稱,而且根本不會複製。一般來說,建議將明確的轉換器與使用絕對路徑作為名稱的資源搭配使用。
將兩個最新的資源複製到目標目錄。
<copy todir="dest" flatten="true"> <first count="2"> <sort> <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/> <resources> <file file="src_dir/file1.txt"/> <file file="src_dir/file2.txt"/> <file file="src_dir/file3.txt"/> <url url="https://ant.dev.org.tw/index.html"/> </resources> </sort> </first> </copy>
緊接在先前範例之後的段落也適用於此範例。
Unix 備註:複製檔案時不會保留檔案權限,它們會變成預設的 UMASK
權限。這是因為目前 Java 執行階段缺乏查詢或設定檔案權限的方法。如果你需要一個保留權限的複製功能,請改用 <exec executable="cp" ... >
。
Windows 備註:如果你複製一個檔案到已經存在但大小寫不同的目錄中,複製的檔案會沿用原始檔案的大小寫。解決方法是在複製檔案之前,刪除目標目錄中的檔案。
重要的編碼備註:過濾二進位檔案時會損毀的原因,是因為過濾涉及使用 Reader 類別讀取檔案。這有一個指定檔案編碼方式的編碼。有許多不同的編碼類型,包括 UTF-8、UTF-16、Cp1252、ISO-8859-1、US-ASCII 和(許多)其他類型。在 Windows 中,預設字元編碼為 Cp1252,在 Unix 中,通常為 UTF-8。這兩種編碼都有非法的位元組序列(UTF-8 比 Cp1252 多)。
Reader 類別如何處理這些非法序列取決於字元解碼器的實作。目前的 Sun Java 實作是將它們對應到合法的字元。先前的 Sun Java(1.3 及更早版本)會擲回 MalformedInputException
。IBM Java 1.4 也會擲回這個例外。造成損毀的是字元的對應。
在 Unix 上,預設通常為 UTF-8,這是一個大問題,因為很容易編輯一個檔案來包含非美國 ASCII 字元,例如 ISO-8859-1 的丹麥文 œ 字元。當這被 Ant(使用過濾)複製時,字元會轉換成問號(或類似字元)。
Ant 沒有辦法做太多事。它無法找出哪些檔案是二進位的—韓文的 UTF-8 版本會有許多位元組設定最高位元。它不會由目前的 Sun Java 實作得知非法字元序列。
過濾僅包含美國 ASCII 的一個技巧是使用 ISO-8859-1 編碼。這似乎不包含非法字元序列,而較低的 7 個位元是美國 ASCII。另一個技巧是將 LANG
環境變數從類似 us.utf8
的東西變更為 us
。