linux不同目录移动文件,将文件移动到不同的linux目录

继续我的评论,大多数新的C程序员都感到困惑,因为他没有仔细考虑整个问题。你根本无法期望拨打rename并让它处理整个过程。 C库函数通常只做一件事,只有一件事。程序员应该从头到尾思考过程,并编写rename或readdir函数未提供的所有其他难题。

例如,如果你计划传递一个新的目录名称,你需要验证,你打算过移动文件的目录,是否确实存在(或者您需要创建它)。你如何测试新目录的存在?您还需要确定和验证格式为新的目录您将rename文件。它是否包含尾随'/'?如果它如何处理?

如果您只想移动具有特定扩展名的文件,则必须开发一种方法来检查并获取由readdir返回的每个文件名的扩展名。一旦我有当前文件的扩展名,我如何将它与目标扩展名进行比较?

最后,如何将我打算移动匹配文件的目录名与当前文件名结合起来以创建将文件移动到的完整路径?所有这些都是您需要提供的一些代码,以便能够将文件从一个目录移动到另一个目录。难以做到吗?不是。这很容易,但是您必须在该级别进行思考并提供最低数量的验证以确定您打算移动的任何单个文件的成功/失败。

而不是去探索如何创造每个单独的难题,因为我明白你需要帮助,而且它确实有助于有一个合理的“过去”来帮助你牢记各种难题,下面是一个简短的例子,它能够完成我理解你的问题的要求。下面以目录中搜索作为第一参数,扩展来搜索作为秒参数,并且相对或绝对路径名任何匹配的文件移动到作为第三参数(默认为.(搜索当前目录),用于文件名与"mkv"扩展,并移动到video子目录):

#include

#include

#include

#include /* PATH_MAX */

#include /* opendir */

#include /* opendir, readdir */

#include /* errno */

#include /* for file constants */

#include /* open/close */

int dir_exists (char *d);

char *fn_ext (char *fn);

char *fn_wext (char *s);

char *stripfwd (char *fn);

int main (int argc, char **argv) {

DIR *dp = opendir (argc > 1 ? argv[1] : ".");/* open directory (. default)*/

struct dirent *de = NULL; /* ptr to dirent for readdir */

char *srchext = argc > 2 ? argv[2] : "mkv", /* extension to search for */

*newdir = argc > 3 ? argv[3] : "./video",/* ptr newdir (video default)*/

path[PATH_MAX] = ""; /* array for trimmed newdir */

strcpy (path, newdir); /* copy newdir from read-only memory to array */

stripfwd (path); /* check for trailing '/' & overwrite with '\0' */

if (!dir_exists (path)) { /* validate new directory exists */

fprintf (stderr, "error: directory not found '%s'.\n", path);

return 0; /* or create/validate directory here */

}

while ((de = readdir (dp))) /* for each file in directory */

{

char *ext = NULL;

/* skip dot files */

if (!strcmp (de->d_name, ".") || !strcmp (de->d_name, ".."))

continue;

if ((ext = fn_ext (de->d_name)) == NULL) /* get file extension */

continue;

if (strcmp (srchext, ext) == 0) { /* if extensions match */

char newpath[PATH_MAX] = "", /* char array for newpath */

*fn = fn_wext (de->d_name); /* ptr to filename only */

sprintf (newpath, "%s/%s", path, fn); /* create newpath */

errno = 0;

if (rename (de->d_name, newpath) == -1) { /* rename/validate file */

fprintf (stderr, "error: move of '%s' to '%s' failed.\n",

de->d_name, newpath);

/* check errno here */

}

else /* output successful result */

printf ("moved '%s' to '%s'.\n", de->d_name, newpath);

}

}

return 0;

}

/** atomic test that directory exists (>=1 success, 0 otherwise)

* NOTE: no directory is actually created. fail occurs instead.

*/

int dir_exists (char *d)

{

int flags = O_DIRECTORY | O_RDONLY;

int mode = S_IRUSR | S_IWUSR;

int fd = open (d, flags, mode);

if (fd < 0) /* directory does not exist */

return 0;

else if (fd) { /* directory exists, rtn fd */

close (fd);

}

return fd;

}

/** Separates extension component from full filename string.

* Returns pointer following last '.' as extension, NULL otherwise.

* Protects against false return of ext followin '.' path.

* No memory is allocated, create copy of return to preserve.

*/

char *fn_ext (char *fn)

{

char *sp = NULL; /* start pointer */

char *ext;

if (!fn) return NULL;

if ((sp = strrchr (fn, '/'))) /* test for '/' to eliminate '.' in path */

sp++;

else

sp = fn;

if ((ext = strrchr (sp, '.')))

{

if (ext == fn) /* dot file case */

return NULL;

ext++;

}

else

ext = NULL;

return ext;

}

/** Separates filename component (with extension) from full filename string.

* Returns pointer following last '/' filename, full-string otherwise.

* No memory is allocated, create copy of return to preserve.

*/

char *fn_wext (char *s)

{

char *fn;

if ((fn = strrchr (s, '/')))

fn++;

else

fn = s;

return fn;

}

/** remove forward slash '/' at end of 'fn' */

char *stripfwd (char *fn)

{

size_t len = strlen (fn);

while (len && fn[len - 1] == '/')

fn[--len] = 0;

return fn;

}

实施例在当前目录的文件

$ l myvideo_*

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_1.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_2.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_3.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_4.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_5.mkv

空的 '视频' 目录

$ l video

total 28

drwxr-xr-x 2 david david 4096 Apr 21 21:45 .

drwxr-xr-x 15 david david 24576 Apr 21 21:46 ..

编译/构建

$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/readdir_rename readdir_rename.c

示例使用/输出

$ ./bin/readdir_rename . mkv video

moved 'myvideo_2.mkv' to 'video/myvideo_2.mkv'.

moved 'myvideo_1.mkv' to 'video/myvideo_1.mkv'.

moved 'myvideo_3.mkv' to 'video/myvideo_3.mkv'.

moved 'myvideo_4.mkv' to 'video/myvideo_4.mkv'.

moved 'myvideo_5.mkv' to 'video/myvideo_5.mkv'.

确认移动

$ l video

total 28

drwxr-xr-x 2 david david 4096 Apr 21 21:46 .

drwxr-xr-x 15 david david 24576 Apr 21 21:46 ..

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_1.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_2.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_3.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_4.mkv

-rw-r--r-- 1 david david 0 Apr 21 21:46 myvideo_5.mkv

看东西了,让我知道,如果你有任何问题。它本身并不难,但有很多需要考虑的是提供一个合理的强有力的举措(可以添加更多验证,这只是一个最小示例)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值