система Win10, FS — NTFS
Наткнулся на проблему на ровном месте. Создаётся файл с помощью fopen с доступом "at" (можно и "wt"), через какое-то время закрывается и переименовывается в другой (типа, складывается архив). На месте него создаётся новый с именем, которое было у предыдущего до переименования. С датами последней записи, последнего доступа и последней модификации всё в порядке. А вот дата создания получается старая, такая же, какая была у предыдущего файла до переименования.
Здравствуйте, Maniacal, Вы писали:
M>система Win10, FS — NTFS M>Наткнулся на проблему на ровном месте. Создаётся файл с помощью fopen с доступом "at" (можно и "wt"), через какое-то время закрывается и переименовывается в другой (типа, складывается архив). На месте него создаётся новый с именем, которое было у предыдущего до переименования. С датами последней записи, последнего доступа и последней модификации всё в порядке. А вот дата создания получается старая, такая же, какая была у предыдущего файла до переименования.
Файл как переименовывается? Какой код?
Здравствуйте, Maniacal, Вы писали:
M>Здравствуйте, Carc, Вы писали:
C>>Файл как переименовывается? Какой код?
M>Сишная функция rename. M>
M>rename(acOldLogPathName, acNewLogFileName)
M>
M>В FAR'е видно, что успешно исчезает исходный файл и появляется переименованный. В дебаге функция тоже возвращает 0 (нет ошибок). M>UPD: VC++2015
А что сама C-шная rename вызывает?
В Винде есть несколько вариантов переименования\перемещения.
См. на MoveFileEx + флаг MOVEFILE_COPY_ALLOWED
Здравствуйте, Carc, Вы писали:
C>А что сама C-шная rename вызывает? C>В Винде есть несколько вариантов переименования\перемещения. C>См. на MoveFileEx + флаг MOVEFILE_COPY_ALLOWED
В disassembly дебаггер что-то не очень стремится нутро CRT показывать даже после включения загрузки символов, но тут проблема не в rename явно, а в fopen. Если создавать файл, который недавно был в файловой системе, то дата создания берётся от удалённого файла. Если хотя бы одну букву поменять в имени, то всё нормально. С костылями я смогу это обойти или через WinAPI тоже, напрямую задавая дату создания. Но коллеги не оценят, если догадаются заглянуть в код. Всё лицо разобьют себе фейспалмом. Не в тех годах я уже такими костылями заплатки в коде делать. Хотелось по-человечески. И главное разобраться за что. Косвенно где-то всплывают наводки, что это последствия зашитого в API функционала по сохранению даты создания файла при его копировании в другое место. Но тут и место то же, и файл не копируется, а создаётся новый.
Как вариант, и именно чтоб капитал пробрести и невинность соблюсти, можно сначала писать не в только что удаленный файл (ну тот, который удалили\переименовали в архив или типа того), а в некий temp-файл (с каким-нить временным случайным именем).
А когда запись заканчивается, и файл закрывается, то переименовывать его в то саоме, первое имя, которое удаляли\переименовыввали.
Только сдается мне это все равно костыли. Чего там сама NTFS надумает, так оно и будет.
Можно конечно еще посмотреть на SetFileTime, но опять же WIndows Specific...
В общем, WinAPI CreateFile ведёт себя так же. Если файл с таким именем недавно был замечен в файловой системе, то при создании нового дата создания берётся от бывшего, хоть его и нет уже.
Поправить получается кодом
Но у меня от такого кода глаза мироточить начинают. Но дата создания становится равна дате последнего доступа. Может комп перезагрузить, а то винда с таким аптаймом мне и похуже сюрпризы порой преподносила.
Здравствуйте, Maniacal, Вы писали:
M>В общем, WinAPI CreateFile ведёт себя так же. Если файл с таким именем недавно был замечен в файловой системе, то при создании нового дата создания берётся от бывшего, хоть его и нет уже. M>Поправить получается кодом M>
M>Но у меня от такого кода глаза мироточить начинают. Но дата создания становится равна дате последнего доступа. Может комп перезагрузить, а то винда с таким аптаймом мне и похуже сюрпризы порой преподносила.
Ну дык я к тому и клоню, что все это NTFS-specific. И или уж что-то танце-бубнить в WinAPI, или уж полагаться на C-шную ширму renaме. Но только что там де факто за ширмой!?!
PS: я бы все эти в CreateFile+SetFileTime в auto-стиль завернул, разве что.
Чего нить типа такого псевдо-кода — думаю мысль понятна...
class CMyFile(LPCTSTR lpszPathName) {//конструктор
тут всякие CreateFile + проверка возвращенного HANDLE (файла)
}
~CMyFile {//деструктор
тут всякие SetFileTime
}
private:
void opeator new(size_t);//хрен вам! А не создание в куче. Только на стеке!
}
Здравствуйте, Maniacal, Вы писали:
M>Здравствуйте, Carc, Вы писали:
M>В общем, WinAPI CreateFile ведёт себя так же. Если файл с таким именем недавно был замечен в файловой системе, то при создании нового дата создания берётся от бывшего, хоть его и нет уже.
That is by design. If a file is created with the name of a just-deleted file, timestamps, attributes, and security are carried forward.
Reason: Plenty of apps delete and recreate on saving, as opposed to truncating the existing file and writing the new contents. This feature fixes the (for the user unexpected) behaviour that security settings and all that suddenly disappear.
If you rename or delete a file, then restore it shortly thereafter, Windows searches the cache for file information to restore. Cached information includes its short/long name pair and creation time.
Здравствуйте, Maniacal, Вы писали:
M>система Win10, FS — NTFS M>Наткнулся на проблему на ровном месте. Создаётся файл с помощью fopen с доступом "at" (можно и "wt"), через какое-то время закрывается и переименовывается в другой (типа, складывается архив). На месте него создаётся новый с именем, которое было у предыдущего до переименования. С датами последней записи, последнего доступа и последней модификации всё в порядке. А вот дата создания получается старая, такая же, какая была у предыдущего файла до переименования.
Это для совместимости с MS-DOS сделано. Называется File Tunneling От языка и его runtime не зависит .
Здравствуйте, Maniacal, Вы писали:
M>система Win10, FS — NTFS M>Наткнулся на проблему на ровном месте. Создаётся файл с помощью fopen с доступом "at" (можно и "wt"), через какое-то время закрывается и переименовывается в другой (типа, складывается архив). На месте него создаётся новый с именем, которое было у предыдущего до переименования. С датами последней записи, последнего доступа и последней модификации всё в порядке. А вот дата создания получается старая, такая же, какая была у предыдущего файла до переименования.
создай файл с рандомным именем, а потом сразу переименуй его в тот, куда будешь записывать свои логи
Здравствуйте, wl., Вы писали:
wl.>создай файл с рандомным именем, а потом сразу переименуй его в тот, куда будешь записывать свои логи
Был и такой вариант обхода проблемы. Всё равно не красиво. Решил насильной установкой даты создания через WinAPI. Всё равно кросс-платформенность в данном конкретном проекте не требуется.