我想为move(mv)Unix命令编写自己的代码。我是C语言的新手,显然在如何修复我的代码上丢失了。如果两个输入都是文件名,我想执行重命名文件等操作。如果dest_folder是一个目录,我想将文件移动到目录中。
但我无法修复特定问题的代码,因为我对目录和C不太熟悉。该程序需要2个输入源和目标,然后执行必要的功能。我显然能够重命名我的文件,但我无法将文件移动到特定文件夹由于某种原因我不知道?
需要有关将文件移动到特定目录的帮助。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
</parent>
答案 0 :(得分:1)
如您所知,mv是通过重命名实现的。 rename是一个原子系统调用,可以将文件重命名为文件,将emtpy目录重命名为空目录或目录的目录(dest必须为nonentity)。因此有以下情况需要处理:
mv file1 file2 - 使用重命名功能
mv dir1 dir2(无效或空) - 使用重命名功能
mv dir1 dir2(非空) - 将dir1重命名为dir2 / dir1
mv file dir(exists) - 将文件重命名为dir / file
mv dir文件 - 非法操作
答案 1 :(得分:0)
rename(3)
无法按照您希望的方式运作(我不知道为什么,请问委员会)。你无法做rename(some_file, some_directory)
,就像man-page所说的那样。
只需使用stat(2)
(或lstat(2)
,如有必要)并检查您获得了什么。这是一个简短的,可运行的草图。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
// check if it is the same inode on the same device
#define SAME_INODE(a, b) ((a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev)
// ALL CHECKS OMMITTED!
int main(int argc, char **argv)
{
struct stat statbuf_src, statbuf_dest;
char *src, *dest, *new_src, *new_dest;
char *current_directory;
if (argc != 3) {
fprintf(stderr, "usage: %s src dest\n", argv[0]);
exit(EXIT_FAILURE);
}
// work on copy
src = malloc(strlen(argv[1]) + 1);
dest = malloc(strlen(argv[2]) + 1);
strcpy(src, argv[1]);
strcpy(dest, argv[2]);
stat(src, &statbuf_src);
stat(dest, &statbuf_dest);
// there are many more, of course
printf("\"%s\" is a ", src);
if (S_ISREG(statbuf_src.st_mode)) {
puts("a regular file");
}
if (S_ISDIR(statbuf_src.st_mode)) {
puts("a directory");
}
printf("\"%s\" is a ", dest);
if (S_ISREG(statbuf_dest.st_mode)) {
puts("a regular file");
}
if (S_ISDIR(statbuf_dest.st_mode)) {
puts("a directory");
}
if (SAME_INODE(statbuf_dest, statbuf_src)) {
printf("%s and %s are the identical\n", src, dest);
}
// if that is not set you have to do it by hand:
// climb up the tree, concatenating names until the inodes are the same
current_directory = getenv("PWD");
printf("current directory is \"%s\"\n", current_directory);
// I'm pretty sure it can be done in a much more elegant way
new_src = malloc(strlen(src) + 1 + strlen(current_directory) + 1);
strcpy(new_src,current_directory);
strcat(new_src,"/");
strcat(new_src,src);
printf("new_src = %s\n",new_src);
new_dest = malloc(strlen(dest) + 1 + strlen(current_directory) + 1 + strlen(src) + 1);
strcpy(new_dest,current_directory);
strcat(new_dest,"/");
strcat(new_dest,dest);
strcat(new_dest,"/");
strcat(new_dest,src);
printf("new_dest = %s\n",new_dest);
if(rename(new_src,new_dest) != 0){
fprintf(stderr,"rename failed with error %s\n",strerror(errno));
}
free(new_src);
free(new_dest);
free(src);
free(dest);
exit(EXIT_SUCCESS);
}
修改:为下面的解释添加了代码 最后你有一个你所在的路径,如果给出的参数是目录或常规文件和路径的信息。如果源是常规文件而目标是目录,则将路径连接到常规文件的名称,带有目录名称的路径和常规文件的名称(源)
出于
Path = /home/foo
src = bar
dest = coffee
构建
new_src = /home/foo/bar
new_dest = /home/foo/coffee/bar
这样对rename()
的调用是
rename(new_src, new_dest);
这样您就可以将常规文件重命名为rename()
接受的常规文件。
请注意,rename()
在每个文件系统中都不起作用,但大多数都是。