複製

說明

將檔案或資源集合複製到新的檔案或目錄。預設情況下,檔案只會在來源檔案比目標檔案新,或當目標檔案不存在時才會複製 - 請參閱 granularity 屬性以了解 Ant 中較新的定義。不過,您可以使用 overwrite 屬性明確覆寫檔案。

資源集合 用於選取要複製的檔案群組。若要使用資源集合,必須設定 todir 屬性。請注意,有些資源(例如 檔案 資源)會傳回絕對路徑作為名稱,而未透過嵌套映射器(或 flatten 屬性)使用它們的結果可能與您的預期不同。

請注意:如果您在複製作業中使用篩選器,則應將複製限制為文字檔案。複製作業會損毀二進位檔案。這適用於由 filter 工作隱含定義或明確提供給複製作業的 filtersets 的篩選器。請參閱 編碼註解

參數

屬性 說明 必要
檔案 要複製的檔案。 是,除非使用嵌套資源集合元素
preservelastmodified 讓複製檔案的最後修改時間與原始來源檔案相同。 否;預設為 false
tofile 要複製到的檔案。在 Apache Ant 1.8.2 之前,tofile 屬性僅支援從中複製的 檔案資源 使用 file 屬性時,可以使用 tofiletodir
使用嵌套資源集合元素時,如果包含的資源數量大於 1,或如果在 <fileset> 中僅指定 dir 屬性,或如果也指定 file 屬性,則僅允許 todir
todir 要複製到的目錄。
overwrite 即使目標檔案較新,也覆寫現有檔案。 否;預設為 false
force 覆寫唯讀目標檔案。自 Ant 1.8.2 起 否;預設為 false
過濾 指出在複製期間是否應使用 全域建置檔案過濾器 進行標記過濾。注意:即使未指定此屬性,或其值為 falsenooff,仍將始終使用巢狀 <filterset> 元素。 否;預設為 false
扁平化 忽略來源檔案的目錄結構,並將所有檔案複製到 todir 屬性指定的目錄中。請注意,您可以使用 扁平化對應器 來達成相同的目的。 否;預設為 false
includeEmptyDirs 複製 FileSet 中包含的任何空目錄。 否;預設為 true
failonerror 如果為 false,則在複製檔案不存在或其中一個巢狀檔案集指向不存在的目錄,或複製時發生錯誤時,記錄警告訊息,但不要停止建置。 否;預設為 true
quiet 如果為 truefailonerrorfalse,則在複製檔案不存在或其中一個巢狀檔案集指向不存在的目錄,或複製時發生錯誤時,不要記錄警告訊息。自 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