Ant копирует файлы без перезаписи

#java #ant #build

#java #ant #сборка

Вопрос:

Есть ли в ant какая-либо команда для копирования файлов из одной структуры папок в другую без проверки даты / времени последнего изменения при перезаписи файлов. В принципе, я хочу, чтобы все дополнительные файлы из папки A были перенесены в папку B. То есть: никакие файлы из папки B не заменяются, но дополнительные файлы из папки A попадают в папку B.

Я видел команды «ant copy» и «ant move», но это не помогло. Есть предложения.

Комментарии:

1. вы пробовали использовать ant copy с overwrite=»true»?

2. могу я спросить, почему вы добавили тег maven-2? вы говорите о ant, встроенном в maven?

3. Большинство людей, использующих maven, пришли из ant background, кроме того, вы правы, я всегда могу встроить ant в maven.

4. вот о чем я спрашиваю: у вас есть рабочий процесс ant или рабочий процесс maven со встроенным выполнением antrun?

Ответ №1:

Атрибут перезаписи задачи копирования Ant гласит: «Перезаписать существующие файлы, даже если файлы назначения более новые».

Таким образом, установка значения false предотвращает их перезапись только в том случае, если они новее, но если исходные файлы новее, они перезаписываются независимо ни от чего.

Единственный способ, который я нашел, чтобы обойти это, — это коснуться целевых файлов перед копированием, т.е:

 <touch>
  <fileset dir="${dest.dir}"/>
</touch>
<copy todir="${dest.dir}" overwrite="false">
  <fileset dir="${src.dir}"/>
</copy>
  

Ответ №2:

вы можете сделать это следующим образом:

Скопируйте один файл

 <copy file="myfile.txt" tofile="mycopy.txt"/>
  

Скопируйте один файл в каталог

 <copy file="myfile.txt" todir="../some/other/dir"/>
  

Скопируйте каталог в другой каталог

<копировать в каталог=»../new/dir»><каталог набора файлов=»src_dir»/></копировать>

Скопируйте набор файлов в каталог и многое другое…

пожалуйста, смотрите эту ссылку для получения дополнительной информации.Задача копирования

Комментарии:

1. Как переименовать файл?

2. Переименовывает файл foo.jar в ${name}-${version}.jar (предполагается, что имя и версия являются предопределенными свойствами). <переименовать src=»foo.jar » dest=»${name}-${version}.jar»/> Если файл с именем ${name}-${version}.jar уже существует, он будет удален перед переименованием foo.jar.

3. Привет, большое спасибо. Теперь задача <переименовать> устарела, и я мог бы использовать задачу <переместить> для выполнения переименования.

Ответ №3:

Во время <touch> работы он обновляет даты файлов в месте назначения и, как таковой, не совсем соответствует запросу.

Согласно документации, если у вас есть хотя бы Ant 1.6.2, вы можете использовать атрибут granularity.

Количество миллисекунд, которое необходимо предоставить, прежде чем решить, что файл устарел. Это необходимо, потому что не каждая файловая система поддерживает отслеживание времени последнего изменения до уровня миллисекунд. Значение по умолчанию составляет 1 секунду, или 2 секунды в системах DOS. Это также может быть полезно, если исходные и целевые файлы находятся на разных компьютерах с несинхронизированными часами. начиная с Ant 1.6.2.

просто установите для него большое число. Я использую 9223372036854, которому должно быть около 292 лет (вероятно, этого достаточно). (Я просто вырезал последние 6 цифр из Long.max), чего достаточно, чтобы не генерировать предупреждения о будущих датах

 <copy todir="${dest.dir}" overwrite="false" granularity="9223372036854">
  <fileset dir="${src.dir}"/>
</copy>
  

это гарантирует, что, если файлы вообще существуют, задача ant будет считать их недостаточно старыми и, следовательно, не перезаписанными (а также не затронутыми другой задачей)

Комментарии:

1. Лучший ответ, поскольку он не изменяет никаких атрибутов файла в целевой системе.

2. Есть ли способ для Ant выдать предупреждение или сообщение о том, что копия файла не была выполнена?

Ответ №4:

Если нет элегантного решения, вы всегда можете сделать это последовательно:

  1. <move> папка <B> в <C>
  2. <copy> файлы из папки <A> в <B>
  3. <copy> файлы из папки <C> в <B> с помощью overwrite=true

(Делайте все наоборот, заменяя новые файлы, а не старые)

Комментарии:

1. Это не помогло, потому что дата и время последнего изменения остаются неизменными, даже если файлы скопированы в папку C.

2. Итак, на шаге 3 он не заменяет файлы, потому что файлы папки B (скопированные из папки A) были изменены после файлов в папке C, поэтому проблема остается той же.

Ответ №5:

Простое решение вашей проблемы — использовать параметр overwrite для команды copy. Это гарантирует, что файлы не будут заменены

     <copy todir="B" verbose="true" overwrite="false">
        <fileset dir="A"/>
    </copy>
  

Более сложным примером является использование селектора набора файлов

     <copy todir="B" verbose="true">
        <fileset dir="A">
            <present targetdir="B" present="srconly"/>
            <date datetime="01/01/2001 12:00 AM" when="after"/>
        </fileset>
    </copy>
  

В этом примере я использовал селектор present для выбора файла, которого нет в целевом каталоге (функционально аналогично проверке перезаписи), и я добавил дополнительное условие date, чтобы проверить, был ли файл изменен с определенной даты.

Список селекторов довольно обширный.

Ответ №6:

Просто используйте <copy> тег с набором файлов в качестве **/* и явно установите для атрибута overwrite значение false. Я использую это постоянно:

 <copy todir="/your/target" overwrite="false">
  <fileset dir="/your/source" />
</copy>
  

Комментарии:

1. включение **/* является избыточным. Это то, что <fileset> выполняется по умолчанию.

2. Флаг overwrite = «false» гарантирует, что файлы не будут скопированы дважды

3. Это неправильно. По умолчанию перезапись имеет значение false, то, что у вас есть выше, на самом деле является настройками copy по умолчанию. overwrite=»false» означает не перезаписывать, если целевой файл более новый, он всегда будет перезаписываться, если целевой файл старше.

4. Это неправильно не потому, что это значение по умолчанию. Просто лишнее 🙂 Иногда я считаю, что лучше повторить значение по умолчанию, чтобы выразить намерение того, что вы делаете.

5. @JoeriHendrickx это работает, конечно <include name="**/*"> , это не игла