简体   繁体   English

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

[英]Unix: Copy file from current to another directory in C

I am trying to make a copy program that allows me to copy file from current directory to another directory. 我正在尝试制作一个允许我将文件从当前目录复制到另一个目录的复制程序。 I am using open(), creat(), read(), write() so far. 到目前为止,我正在使用open(),creat(),read(),write()。

For example: So far i can only copy the file to my current directory. 例如:到目前为止,我只能将文件复制到当前目录。

I have a folder name A_folder and a file name file_1 and i want to copy file_1 from my current directory to A_folder . 我有一个文件夹名称A_folder和一个文件名file_1 ,我想将文件_1从当前目录复制到A_folder

Can someone please help me? 有人可以帮帮我吗?

Code and image are shown below 代码和图像如下所示

What I can do now: ./copy file1 copy_file 我现在可以做什么:./copy file1 copy_file

What I want is: ./copy file1 ./folder copy_file 我想要的是:./copy file1 ./folder copy_file

  1. You need a helper function that constructs the path you need, A_folder/file_1 , when given A_folder and file_1 . 当给定A_folderfile_1时,您需要一个辅助函数A_folder/file_1来构造所需的路径。

    A typical example of such a function is 此类功能的典型示例是

     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; } 

    Note that the above function returns a dynamically allocated copy, so you should free() the result when you no longer need it. 请注意,上面的函数返回一个动态分配的副本,因此,当您不再需要结果时,应将其free()

  2. I prefer much more explicit error checking. 我更喜欢更明确的错误检查。 Consider: 考虑:

     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; } 

    Note the pattern how I use p and q pointers to write the read buffer contents in possibly more than one part. 请注意该模式,我如何使用pq指针以可能不止一个部分的方式写入读取缓冲区的内容。 This can occur, if the source file is local, and the target file is on some wonky filesystem. 如果源文件是本地文件,而目标文件在某些​​文件系统上,则会发生这种情况。 There is no requirement that write() should either write the entire buffer or return with an error code; 并不要求 write()应该写入整个缓冲区或返回错误代码。 short writes -- where only some of the initial data in the given buffer was written -- are perfectly okay, and do occur in some situations. 短写(只写给定缓冲区中的一些初始数据)完全可以,并且在某些情况下确实会发生。 The above is my preferred way to handle those. 以上是我处理这些问题的首选方式。

    Many consider this level of error checking -- especially checking the result value of close() , since at this point in time many operating systems (including Linux) never return an error there -- foolish or at least paranoid. 许多人认为这种级别的错误检查-特别是检查close()的结果值,因为此时许多操作系统(包括Linux)从不向那里返回错误-愚蠢或至少偏执。

    I personally consider this kind of error checking "robust" , because I want my code to tell me, as the user, if anything untoward happened; 我个人认为这种错误检查“健壮” ,因为我希望我的代码以用户的身份告诉我是否发生了任何不幸的事情。 I definitely do not want it to just assume everything went fine, I want it to be paranoid about it. 我绝对不希望它只是假设一切都很好,我希望它对此感到偏执。 (I am not saying that OP's code does not check error codes; I'm only saying this version is more careful and vocal about it.) (我并不是说OP的代码不会检查错误代码;我只是说这个版本更加谨慎和直言不讳。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM