[英]Sorting files based on their filetype
下面的程序用于根据文件类型对文件进行分类,更准确地说是它们的扩展名。 例如使用的命令./sorting -f file1.jpg file2.txt file3.c
然后它会创建jpg
、 txt
和c
文件夹并将文件放入其中。
这是代码
#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.c
和stderr.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
$
运行程序( mf29
从mf29.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.