繁体   English   中英

根据文件类型对文件进行排序

[英]Sorting files based on their filetype

下面的程序用于根据文件类型对文件进行分类,更准确地说是它们的扩展名。 例如使用的命令./sorting -f file1.jpg file2.txt file3.c然后它会创建jpgtxtc文件夹并将文件放入其中。

这是代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>

void *check(char *argv[]);
void *mkdir(char *argv[]);
void *mvdr(char *argv[]);
pid_t child;

int main(int argc, char *argv[]) {
    pthread_t files[argc];  // inisialisasi awal
    int iret[argc];

    // 1. how many threads you need, setiap file
    //      -- setiap file setiap argc & argv

    // create thread every files
    if (argc == 1)
        return 0;

    if (strcmp(argv[1], "-f") == 0) {
        for (int i = 2; i < argc; ++i) {
            iret[i] = pthread_create( &files[i], NULL, check, argv[i]); // membuat thread pertama
        }
    }
    return 0;
}

void *check(char *argv[]) {
    pthread_t move, make;
    int types = 0;
    int imv, imk;
    char type[80] = {0};
    char *tok = NULL;

    tok = strtok(argv, ".");
    while (tok) {
        strcpy(type, tok);
        tok = strtok(NULL, ".");

        imv = pthread_create(&make, NULL, mkdir, argv);

        imk = pthread_create(&move, NULL, mvdr, argv);

        pthread_join(mkdir, NULL);
        pthread_join(mvdr, NULL);
    }
}

void *mkdir(char *argv[]) {
    child = fork();

    if (child == 0) {
        char *mkdr[3] = { "mkdir", argv, NULL };
        execv("/usr/bin/mkdir", mkdr);
    }
}

void *mvdr(char *argv[]) {
    child = fork();

    if (child == 0) {
        char *mv[5] = { "mv", "-v", argv, argv, NULL };
        execv("/usr/bin/mv", mv);
    }
}

我正在使用execv来制作和移动文件。 它必须与线程、管道或套接字有关。 你知道如何解决它吗? 非常感谢您的帮助

不清楚对课堂练习有什么限制,我的印尼语不如OP的英语,Chrome似乎也不愿意翻译GitHub页面https://github上的README.md文件。 com/VYPRATAMA009/sisop-modul-3

解决问题中描述的问题(就期望的结果而言),不需要使用线程或fork()exec*()来实现程序。

将线程与fork()exec*()混合使用几乎总是一个坏主意——选择多线程或多处理,但不要同时选择。

程序需要处理选项( -f只检查常规文件;省略移动任何文件类型),然后处理任何残留的文件名。 名称处理包括检查常规文件(如果需要strrchr() ,使用strrchr()查找扩展名,然后使用该扩展名创建一个目录,然后在子目录中格式化名称,然后重命名文件以使其进入目录,并释放分配的内存。

#include "stderr.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

static bool is_regular(const char *filename);
static void mk_directory(const char *dirname);
static void move_file(const char *filename);

static bool check_file = false;

static const char usestr[] = "[-f] file [...]";
static const char optstr[] = "f";

int main(int argc, char *argv[])
{
    int opt;
    err_setarg0(argv[0]);

    while ((opt = getopt(argc, argv, optstr)) != -1)
    {
        switch (opt)
        {
        case 'f':
            check_file = true;
            break;
        default:
            err_usage(usestr);
            /*NOTREACHED*/
        }
    }

    if (optind == argc)
        err_usage(usestr);

    for (int i = optind; i < argc; i++)
        move_file(argv[i]);

    return 0;
}

static bool is_regular(const char *filename)
{
    struct stat sb;
    if (stat(filename, &sb) != 0)
        err_syserr("failed to get status of file '%s': ", filename);
    return S_ISREG(sb.st_mode);
}

static void mk_directory(const char *dirname)
{
    if (mkdir(dirname, 0755) != 0)
    {
        if (errno != EEXIST)
            err_syserr("failed to create directory '%s': ", dirname);
    }
}

static void move_file(const char *filename)
{
    char *dot = strrchr(filename, '.');
    if (check_file && !is_regular(filename))
    {
        err_remark("'%s' is not a regular file\n", filename);
        return;
    }
    if (dot == NULL || dot == filename || dot[1] == '\0')
    {
        err_remark("file '%s' does not have an extension\n", filename);
        return;
    }
    mk_directory(dot + 1);
    size_t namelen = strlen(dot + 1) + strlen(filename) + sizeof("/");
    char *buffer = malloc(namelen);
    if (buffer == NULL)
        err_syserr("failed to allocated %zu bytes memory: ", namelen);
    sprintf(buffer, "%s/%s", dot + 1, filename);
    if (rename(filename, buffer) != 0)
        err_syserr("failed to rename '%s' to '%s': ", filename, buffer);
    free(buffer);
}

这使用了我在 GitHub 上的SOQ (堆栈溢出问题)存储库中提供的错误报告功能,作为src/libsoq子目录中的文件stderr.cstderr.h

给定一个开始包含以下内容的目录:

$ ls -la
total 56
drwxr-xr-x   15 jonathanleffler  staff   480 Apr  2 22:14 .
drwxr-xr-x  241 jonathanleffler  staff  7712 Apr  2 22:16 ..
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk.
-rw-r--r--    1 jonathanleffler  staff  1036 Apr  2 22:06 binge.c
-rw-r--r--    1 jonathanleffler  staff   666 Apr  2 22:06 garbage.c
-rw-r--r--    1 jonathanleffler  staff  1772 Apr  2 21:11 junk-0.0.1.tar.gz
-rw-r--r--    1 jonathanleffler  staff  1772 Apr  2 21:10 junk-1.txt
-rw-r--r--    1 jonathanleffler  staff  1772 Apr  2 21:10 junk-2.txt
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 junk.
-rw-r--r--    1 jonathanleffler  staff  1772 Apr  2 21:10 junk.c
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:04 junk.dir
prw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:10 junk.fifo
lrwxr-xr-x    1 jonathanleffler  staff     8 Apr  2 21:12 junk.lnk -> junk.dir
-rw-r--r--    1 jonathanleffler  staff   812 Apr  2 22:06 trash.c
$

运行程序( mf29mf29.c编译)产生:

$ mf29 -f .j* *
mf29 -f .j* *
mf29: file '.junk' does not have an extension
mf29: file '.junk.' does not have an extension
mf29: file 'junk.' does not have an extension
mf29: 'junk.dir' is not a regular file
mf29: 'junk.fifo' is not a regular file
mf29: 'junk.lnk' is not a regular file
$ ls -la
total 0
drwxr-xr-x   11 jonathanleffler  staff   352 Apr  2 22:37 .
drwxr-xr-x  241 jonathanleffler  staff  7712 Apr  2 22:16 ..
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk.
drwxr-xr-x    6 jonathanleffler  staff   192 Apr  2 22:37 c
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:37 gz
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 junk.
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:04 junk.dir
prw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:10 junk.fifo
lrwxr-xr-x    1 jonathanleffler  staff     8 Apr  2 21:12 junk.lnk -> junk.dir
drwxr-xr-x    4 jonathanleffler  staff   128 Apr  2 22:37 txt
$

然后在没有-f选项的情况下恢复移动的文件并再次运行会产生:

$ mv ?/* ??/* ???/* ????/* .
$ rmdir ? ?? ??? ????
$ mf29 .j* *
mf29: file '.junk' does not have an extension
mf29: file '.junk.' does not have an extension
mf29: file 'junk.' does not have an extension
$ ls -la
total 0
drwxr-xr-x   11 jonathanleffler  staff   352 Apr  2 22:42 .
drwxr-xr-x  241 jonathanleffler  staff  7712 Apr  2 22:16 ..
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 .junk.
drwxr-xr-x    6 jonathanleffler  staff   192 Apr  2 22:42 c
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:42 dir
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:42 fifo
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:42 gz
-rw-r--r--    1 jonathanleffler  staff     0 Apr  2 22:12 junk.
drwxr-xr-x    3 jonathanleffler  staff    96 Apr  2 22:42 lnk
drwxr-xr-x    4 jonathanleffler  staff   128 Apr  2 22:42 txt
$

如果您提供具有多个路径名组件的名称,这通常会失败:

$ ../mf29 ~/src/cmd/timecmd.c
mf29: failed to rename '/Users/jonathanleffler/src/cmd/timecmd.c' to 'c//Users/jonathanleffler/src/cmd/timecmd.c': error (2) No such file or directory
$

有多种方法可以修复——这取决于所需的结果。 POSIX 函数basename()可能很有用。 函数mkpath()也很有用。

暂无
暂无

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

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