Чтобы переместить (из C) файл из одного места в другое в той же файловой системе, просто используйте переименовать(2) системный вызов.
По крайней мере, для вашего конкретного примера вам нужно будет закодировать:
char* srcpath = "TempFile.txt"; // assume it is a variable path
char destpath[1024];
snprintf (destpath, sizeof(destpath), "../MST/%s", srcpath);
if (rename (srcpath, destpath)) {
// something went wrong
if (errno == EXDEV) {
// copy data and meta data
} else { perror("rename"); exit(EXIT_FAILURE); };
}
else { // the rename succeeded
}
Если вы действительно хотите mv TempFile.txt ../MST/TempFile.txt
только для TempFile.txt
, вы можете просто вызвать rename("TempFile.txt", "../MST/TempFile.txt")
и обработать случаи ошибок, как я предлагаю. Если вы уверены, что ../MST/
лежит в той же файловой системе, что и .
, то EXDEV
не должно происходить и вам не нужно особо с этим разбираться (но нужно обрабатывать ошибки).
Если вы хотите переместить файл между двумя разными файловыми системами, вам нужно скопировать данные (и, возможно, некоторые метаданные) самостоятельно (а затем удалить, например, с помощью удалить(2)) исходный файл). Вы можете обнаружить эту ситуацию различными способами: вы можете просто попробовать rename
и если errno
(см. errno(3)) – это EXDEV
вам нужно скопировать файл. Или вы можете использовать stat(2) для запроса источника метаданные файла (и целевого каталога) - например. его размер и файловая система.
Конечно, вам нужно понимать, что такое файлы в Linux (или Posix), в частности, что такое inode.... См. inode(7) и учетные данные(7)
Вы могли бы использовать system
с /bin/mv
(но будьте осторожны со странными символами, такими как пробелы или точки с запятой, в путях к файлам, вам нужно экранировать их, чтобы избежать внедрение кода), очевидно, вы этого не хотите.
Вам следует поиграть с strace(1) (или, возможно, также ltrace
) на mv
в различных ситуациях, чтобы понять, что он делает. Кроме того, изучите исходный код GNU coreutils, который предоставляет /bin/mv
, особенно в mv.c ...
Некоторые дополнительные библиотеки C или C++ могут предоставить вам функции для перемещения файлов (в одной и той же файловой системе они должны выполнять rename
, в других файловых системах они копируют данные исходного файла и, возможно, некоторые метаданные и отсоединяют источник, поэтому не могут быть атомарными ), например в C g_file_move (из Gio с Glib из Gnome) или на C++ copy_file, за которым следует remove
в Boost и т.д. и т.п....
PS. Для временных файлов см. tmpfile(3), mkstemp(3) и т. д.
person
Basile Starynkevitch
schedule
23.11.2013
mv
— это команда оболочки. - person devnull   schedule 23.11.2013system()
для вызоваmv
, но на самом деле вам следует просто использоватьrename
- person cnd   schedule 23.11.2013-Wall -Wextra -Werror -Wno-unused-parameter
, и я думаю, что это должно быть по умолчанию, поэтому я немного предвзят;). Я действительно не могу себе представить, почему люди будут использовать неявно объявленные функции, но, возможно, в этом есть смысл. - person Jonas Schäfer   schedule 24.11.2013