Создание уникального временного каталога из чистого C в Windows - PullRequest
11 голосов
/ 09 июня 2011

Я хотел бы создать уникальный временный каталог в Windows из некоторого C код (не C ++ или C #). Я хочу сделать это, чтобы я мог поставить некоторую временную файлы в каталоге, а затем удалить их все легко, когда я закончу (путем рекурсивного удаления каталога).

Я, по сути, ищу эквивалент Linux mkdtemp функция. Здесь есть ответ C # здесь , а ответы на это вопрос предложить использовать Boost. Но так как я использую C, эти решения не работают для меня.

Лучшее, что я смог придумать, это использовать GetTempFileName затем CreateDirectory, но проблема в том, что если я спрошу GetTempFileName чтобы создать уникальное имя файла, он также создаст файл (который я не хочу, так как вместо этого я хочу создать каталог).

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

Похоже, что если я хочу создать уникальный каталог, мне придется создать временный файл, получить имя, удалить его, а затем создать каталог с тем же именем - что звучит очень грязно. Есть другие идеи?

Ответы [ 3 ]

9 голосов
/ 09 июня 2011

Вы можете использовать то, что GetTempPath возвращает сцепленным с Guid, чтобы обеспечить уникальность каталога. Вы можете создать Guid, используя UuidCreate или CoCreateGuid Function .

Чтобы рекурсивно удалить каталог, здесь есть пример на чистом C: Как рекурсивно удалить каталог? на основе FindFirstFile, FindNextFile, DeleteFile и RemoveDirectory .

Существует также SHFileOperation , но он более тяжелый и основан на функциях оболочки Windows, а DLL-библиотеки оболочки не всегда нужны, особенно если вы пишете код сервера.

3 голосов
/ 09 июня 2011

Используйте _tempnam tmpnam_s, чтобы создать имя файла, которое еще не существует, а затем используйте CreateDirectory для создания каталога. Технически, если вы делаете это, существует условие гонки, в котором другой процесс может потенциально создать файл или каталог с таким именем в промежутке времени между созданием имени файла и созданием каталога, но вероятность этого довольно маловероятна. Чтобы защититься от этого, вы можете делать петли, пока не добьетесь успеха.

Для рекурсивного удаления дерева каталогов вы можете использовать SHFileOperation. Кроме того, вы можете выполнить обход каталога самостоятельно с помощью FindFirstFile / FindNextFile, DeleteFile и RemoveDirectory .

Если вы хотите удалить каталог автоматически при выходе, зарегистрируйте функцию, используя atexit. Это будет работать только для обычного завершения программы (т. Е. С помощью функции exit или возврата из main / WinMain). Это не будет работать для ненормального завершения программы (например, через abort, нарушение прав доступа, кто-то еще звонит TerminateProcess и т. Д.).

3 голосов
/ 09 июня 2011

Используйте GetTempPath, затем CreateDirectory со случайным именем под ним, при необходимости повторите попытку, если CreateDirectory не удастся из-за того, что он уже существует.Но если ваша генерация имени достаточно хороша, вероятность столкновения с существующим именем намного меньше, чем вероятность того, что блэкхат сможет угадать ваш пароль или даже ваш закрытый ключ, так что вы можете его игнорировать.

...