Как скопировать один файл в другой раздел в Linux, используя C

#c #linux #copy #move #disk-partitioning

#c #linux #Копировать #переместить #разделение диска

Вопрос:

rename (), link() не работают

Спасибо!

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

1. fopen fread fwrite fclose . Разные разделы означают, что вы должны копировать.

Ответ №1:

Вы пробовали использовать стандартные старые функции C?

 `fopen` the source on one partition
`fopen` the destination on the other partition

LOOP while `fread` > 0
   `fread` from the source to a buff
   `fwrite` to the dest from a buff
  

А затем закройте ваши файлы (т.Е. fclose ).

Это также более переносимо.

РЕДАКТИРОВАТЬ: если вы хотели, чтобы это было действительно просто, почему бы просто не использовать язык сценариев (python / bash) и сделать это в нескольких строках.

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

1. особенно легко с чем-то вроде shutil.copy()

2. «Это также более переносимо» — вроде того. Проблема с установкой на реализацию «переносимой копии файла» заключается в том, что разные системы имеют разные метаданные файла, начиная с прав доступа к файлам и заканчивая временем доступа, правами собственности, списками ACL и дополнительными потоками данных. Таким образом, полученная копия переносима, но то, что она делает, не обязательно очень полезно, поскольку она копирует не то, что любой разумный пользователь считает «файлом», а только содержимое файла.

3. Исходный код cp --preserve должен дать представление о том, что еще вы, возможно, захотите скопировать, и как это сделать в Linux.

4. @SteveJessop да, вот почему я выделил курсивом «больше» и предложил использовать функции копирования из Python или bash, а не копировать содержимое файла с помощью функций C.

Ответ №2:

Вот как я бы это сделал. Это довольно просто и оставляет сложную часть фактического копирования cp инструменту, который успешно выполняет эту задачу в течение нескольких лет.

 #include <assert.h>
#include <string.h>

#include <sys/wait.h>
#include <unistd.h>

int
runvp(int *ret_status, const char *command, const char * const *argv)
{
  pid_t pid;
  int status;
  char * const *execv_argv;

  pid = fork();
  if (pid == (pid_t) -1)
    return -1;

  if (pid == 0) {
    /*
     * Circumvent the C type conversion rules;
     * see ISO C99: 6.5.16.1#6 for details.
     */
    assert(sizeof(execv_argv) == sizeof(argv));
    memcpy(amp;execv_argv, amp;argv, sizeof(execv_argv));

    (void) execvp(command, execv_argv);
    return -1;
  }

  if (waitpid(pid, amp;status, 0) == -1)
    return -1;

  *ret_status = status;
  return 0;
}
  

Это оболочка fork , execvp которую я написал несколько лет назад. Его можно использовать следующим образом:

 #include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  int exitcode;
  const char *cmdline[] = {
    "cp",
    "--",
    argv[1],
    argv[2],
    NULL
  };

  if (runvp(amp;exitcode, cmdline[0], cmdline) == -1) {
    perror("runvp");
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
  

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

1. Плохая идея. Вы теряете всякую возможность определить, что пошло не так, если cp обнаружите ошибку, плюс в процессе он будет передавать что-то в stderr, плюс он подберет любой «cp», который окажется на ПУТИ (т. Е. Потенциальная дыра в безопасности), плюс это длиннее и сложнее, чем просто написать свою собственную копиюфункция.

Ответ №3:

rename() должен работать. Вы проверили ошибку, которую он возвращает? rename() возвращает 0, если это удалось в соответствии с документацией:

http://www.cplusplus.com/reference/clibrary/cstdio/rename/

Вы можете использовать perror() для вывода строки ошибки в стандартную ошибку (stderr, обычно экран):

http://www.cplusplus.com/reference/clibrary/cstdio/perror/