gpt4 book ai didi

c - Unix:将文件从当前目录复制到 C 中的另一个目录

转载 作者:太空宇宙 更新时间:2023-11-04 10:21:35 26 4
gpt4 key购买 nike

我正在尝试制作一个复制程序,允许我将文件从当前目录复制到另一个目录。到目前为止,我正在使用 open()、creat()、read()、write()。

例如:到目前为止,我只能将文件复制到当前目录。

我有一个文件夹名称 A_folder 和一个文件名称 file_1 我想将 file_1 从我当前目录复制到 A_folder .

有人可以帮帮我吗?

代码和图片如下所示

我现在能做的:./copy file1 copy_file

我想要的是:./copy file1 ./folder copy_file

最佳答案

  1. 当给定 A_folderfile_1 时,您需要一个辅助函数来构造您需要的路径 A_folder/file_1

    这种函数的一个典型例子是

    char *combine_path(const char *dir, const char *name)
    {
    /* Calculate the lengths of the path components.
    If the respective parameter is NULL, the length is zero .*/
    const size_t dirlen = (dir) ? strlen(dir) : 0;
    const size_t namelen = (name) ? strlen(name) : 0;

    char *path, *p;

    /* We allocate <dir> + '/' + <name> + '\0'. */
    path = malloc(dirlen + namelen + 2);
    if (!path) {
    errno = ENOMEM;
    return NULL;
    }

    /* Let p point to the current position in the
    resulting path. */
    p = path;

    /* If there is a directory part,
    copy it, and append a '/' after it. */
    if (dirlen > 0) {
    memcpy(p, dir, dirlen);
    p += dirlen;
    *p = '/';
    p += 1;
    }

    /* If there is a name part, copy it. */
    if (namelen > 0) {
    memcpy(p, name, namelen);
    p += namelen;
    }

    /* Append a NUL char, '\0', to terminate the
    dynamically allocated buffer.
    This turns it into a C string. */
    *p = '\0';

    /* Return the pointer to the dynamically-allocated
    memory, containing the concatenated paths
    as a single string. */
    return path;
    }

    请注意,上述函数返回一个动态分配的副本,因此您应该在不再需要时free()该结果。

  2. 我更喜欢更明确的错误检查。考虑:

    int copy_file(const char *frompath, const char *topath)
    {
    struct stat frominfo, toinfo;
    char data[BUFFERSIZE];
    ssize_t n;
    int src, dst, cause;

    if (!frompath || !*frompath ||
    !*topath || !*topath) {
    fprintf(stderr, "copy_file(): NULL or empty file name!\n");
    return errno = EINVAL;
    }

    src = open(frompath, O_RDONLY | O_NOCTTY);
    if (src == -1) {
    cause = errno;
    fprintf(stderr, "%s: Cannot open file: %s.\n", frompath, strerror(cause));
    return errno = cause;
    }
    if (fstat(src, &frominfo) == -1) {
    cause = errno;
    fprintf(stderr, "%s: Cannot get file statistics: %s.\n", frompath, strerror(cause));
    return errno = cause;
    }

    dst = open(topath, O_WRONLY | O_CREAT | O_EXCL, frominfo.st_mode & 0777);
    if (dst == -1) {
    cause = errno;
    fprintf(stderr, "%s: Cannot create file: %s.\n", topath, strerror(saved_errno));
    errno = cause;
    }

    while (1) {
    char *p, *q;

    n = read(src, buffer, sizeof buffer);
    if (n == 0) {
    /* End of input. */
    cause = 0;
    break;
    } else
    if (n < 0) {
    /* Error (or interrupt, EINTR). */
    if (n == -1)
    cause = errno;
    else
    cause = EIO; /* n < -1 is a bug. */
    fprintf(stderr, "%s: Read error: %s.\ņ", frompath, strerror(cause));
    break;
    }

    p = buffer;
    q = n;
    cause = 0;
    while (p < q) {
    n = write(dst, p, (size_t)(q - p));
    if (n > 0)
    p += n;
    else
    if (n == -1) {
    cause = errno;
    break;
    else {
    /* Bug; should never occur. */
    cause = EIO;
    break;
    }
    }
    if (cause) {
    fprintf(stderr, "%s: Write error: %s.\n", topath, strerror(cause));
    break;
    }
    }

    /* Failed? */
    if (cause) {
    unlink(topath);
    return errno = cause;
    }

    if (fstat(dst, &toinfo) == -1) {
    cause = errno;
    fprintf(stderr, "%s: Cannot get file information: %s.\n", topath, strerror(cause));
    unlink(topath);
    return errno = cause;
    }

    /* from may be a device; if so, its size
    will be zero. */
    if (frominfo.st_size > 0 &&
    frominfo.st_size != toinfo.st_size) {
    cause = EIO;
    fprintf(stderr, "%s: File size mismatch!\n", topath);
    unlink(topath);
    return errno = cause;
    }

    /* Careful closing. */
    if (close(src) == -1) {
    cause = errno;
    fprintf(stderr, "%s: Error closing file: %s.\n", frompath, strerror(cause));
    unlink(topath);
    return errno = cause;
    }

    if (close(dst) == -1) {
    cause = errno;
    fprintf(stderr, "%s: Error closing file: %s.\n", topath, strerror(cause));
    unlink(topath);
    return errno = cause;
    }

    /* Success. */
    return errno = 0;
    }

    请注意我如何使用 pq 指针将读取缓冲区内容写入可能不止一个部分的模式。如果源文件是本地的,而目标文件位于某个不稳定的文件系统上,则可能会发生这种情况。没有要求 write() 应该写入整个缓冲区或返回错误代码;短写——只写入给定缓冲区中的一些初始数据——是完全可以的,并且在某些情况下确实会发生。以上是我处理这些问题的首选方式。

    许多人考虑这种级别的错误检查——特别是检查 close() 的结果值,因为在这个时间点许多操作系统(包括 Linux)从不返回错误——愚蠢或者至少是偏执狂。

    我个人认为这种错误检查“稳健”,因为我希望我的代码能够告诉我,作为用户,如果发生了任何不幸的事情;我绝对不希望它只是假设一切顺利,我希望它对此偏执。 (我并不是说 OP 的代码不检查错误代码;我只是说这个版本更加谨慎和直言不讳。)

关于c - Unix:将文件从当前目录复制到 C 中的另一个目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43660314/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com