2010-07-01 3 views
3

Я переименовываю файл с помощью boost :: filesystem, и иногда файл цели будет существовать. Согласно повышающей документации здесь:boost :: filesystem :: rename: Не удается создать файл, когда этот файл уже существует

http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/reference.html#Non-member-functions

шаблона недействительным переименования (Const Path1 & from_p, Const Path2 & to_p); Требуется: Path1 :: external_string_type и Path2 :: external_string_type - это того же типа.

Эффекты: Переименовывает from_p в to_p, как если бы POSIX rename().

Постусловия: существует (from_p) & & существует (to_p), а также содержание и атрибуты файла первоначально имени from_p в остальном без изменений.

[Примечание: Если from_p и to_p разрешают тот же файл, никаких действий не предпринимается. Иначе, если to_p разрешает существующий файл , он удаляется. A символическая ссылка сама переименована, , а не файл, который он решает до , переименованный. - конец примечание]

(курсив мой)

При тестировании этого кода, скомпилированного с помощью MS Visual Studio 2008 на XP SP3, переименование бросками повышение :: файловая система :: filesystem_error с сообщением:

Невозможно создать файл, так как уже существует

Замечу, это было поднято в сообщении об ошибке: https://svn.boost.org/trac/boost/ticket/2866

... но гр лаймы, которые будут закрыты в Boost 1.41.0, и я использую Boost 1.42.0.

Я делаю что-то неправильно здесь, или я должен просто вернуться к std :: rename?

Я еще не тестировал это на Linux, но не знаю, существует ли проблема там.

ответ

3

Похоже, что он был исправлен, но только в песочнице «V3» версии Boost.Filesystem, которой пока нет в версиях Boost.

Я тестировал на Boost 1.43.0 на Linux с теми же результатами - на самом деле в отчете об ошибке указывается код нарушения, который явно проверяет существование на POSIX и выдает исключение. Возможно, это было сделано изначально, потому что MoveFile на Windows демонстрирует такое же поведение? В версии песочницы V3 переименование вызовет MoveFileEx на Windows и std::rename на POSIX и позволит перезаписать существующий файл.

Предположим, вы можете обойти это, позвонив по телефону boost::filesystem::remove, прежде чем звонить boost::filesystem::rename, в зависимости от того, нужна ли вашей программе операция атомарной или нет.

+1

Спасибо, я не понял, что исправление не дошло до более широкого мира. Для приложения, которое я разрабатываю, я, вероятно, буду использовать remove/rename, но, как вы говорите, если бы мне было нужно что-то атомное, я бы был набит. –

Смежные вопросы