其目的是在一个文件夹中连接某些文件模式。
abc
字符串
具有带子字符串的文件
score
型
像score_01.csv score_02.csv score_03.csv和类似的100个文件
下面程序的基本概念是接受两个命令行参数,一个是文件夹,另一个是文件模式。
gcc program.c -o program
./program my_folder score
型
程序进入my_folder并开始遍历文件,读取它们,然后将它们推入IPC队列。在程序的开头使用pthread启动了一个消费者。这个消费者必须读取和打印。
似乎我没有正确地做msgsnd或msgrcv
此外,如果我尝试在msgsnd之前打印数据缓冲区,它在Mac OS中的打印方式不同-没有问题,而在Ubuntu中,它打印几行,然后出现分散的文本
// File name program.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
key_t key;
int msgid;
typedef struct {
long msg_type;
char* buffer;
size_t length;
} bufferPack;
char* fileBuffer(char* filename) {
FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
char *string = malloc(fsize + 1);
fread(string, fsize, 1, f);
fclose(f);
return string;
}
void walk_dir(const char *path, char* wildcard)
{
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(path)))
return;
while ((entry = readdir(dir)) != NULL) {
char *name = entry->d_name;
char full_name[1024];
if (strstr(name, wildcard ) == NULL )
continue;
snprintf(full_name, sizeof(full_name), "%s/%s", path, name);
bufferPack pack;
pack.msg_type = 1;
pack.buffer = fileBuffer(full_name);
pack.length = strlen(pack.buffer);
msgsnd(msgid, &pack, sizeof(bufferPack), 0);
}
closedir(dir);
}
void* consumer(void* arg) {
bufferPack pack;
while (1) {
int rec = msgrcv(msgid, &pack, sizeof(bufferPack), 1, 0);
if (rec == -1)
// No message in queue
continue;
printf("%s\n", pack.buffer);
free(pack.buffer);
}
}
int main(int argc, char **argv)
{
if ((key = ftok("/tmp", 'A')) == -1) {
perror("ftok");
exit(EXIT_FAILURE);
}
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
exit(EXIT_FAILURE);
}
pthread_t thread;
pthread_create(&thread, NULL, consumer, NULL);
walk_dir(argv[1], argv[2]);
}
型
1条答案
按热度按时间50few1ms1#
strlen(pack.buffer)
要求缓冲区是一个空终止字符串。但是fileBuffer()
从不添加空终止符(尽管它使用fsize+1
为它分配了空间)。字符串