【问题标题】:How to properly use realpath() for reading multiple files within a directory?如何正确使用 realpath() 读取目录中的多个文件?
【发布时间】:2021-06-12 06:58:00
【问题描述】:

这应该是一个程序,它读取目录中的多个文件并获取给定单词在这些文件中出现的频率,我知道这部分现在不完整。

fopen() 正在将 null 返回到存在并具有权限 777 的文件。

这是来自终端的权限:

ra@ra-VirtualBox:~/Desktop/lab2/folder$ ls -l
total 12
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file1.txt
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file2.txt
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file3.txt

这是this answer建议使用errno后得到的输出

印有buf

READING FILE: /home/ra/Desktop/lab2/file3.txt

fopen: No such file or directory
READING FILE: /home/ra/Desktop/lab2/file1.txt

fopen: No such file or directory
READING FILE: /home/ra/Desktop/lab2/file2.txt

fopen: No such file or directory

编辑:从输出中我注意到realpath() 在转到文件之前以某种方式擦除了整个子目录。 /folder/ 不存在,/home/ra/Desktop/lab2/file*.txt 不存在!

代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <dirent.h>

#include <unistd.h>

#include <pthread.h>

#include <limits.h>       //For PATH_MAX

typedef struct {
  FILE * fptr;
  char * word;

}
inputFile;

void * readFrequenciesFromFile(void * path) {

  static int count = 0;

}

int main(int argc, char * argv) {

  int i;

  char buf[PATH_MAX + 1];
  char * wordToSearch = "test";

  DIR * dir;
  FILE * entry_file;
  struct dirent * in_file;

  // notice that the full directory is used here
  // but buf somehow does magic and tells me the files
  // are in /lab2/ directory
  dir = opendir("/home/ra/Desktop/lab2/folder");

  if (dir == NULL) {
    printf("Error! Unable to read directory");
    exit(1);
  }

  while ((in_file = readdir(dir)) != NULL) {

    if (!strcmp(in_file -> d_name, "."))
      continue;
    if (!strcmp(in_file -> d_name, ".."))
      continue;

    realpath(in_file -> d_name, buf);
    entry_file = fopen(buf, "r");
    // printf("READING FILE: %s\n", buf);
    if (!entry_file) perror("fopen");
    if (entry_file != NULL) {
      pthread_t tid;
      inputFile * args = malloc(sizeof * args);
      args -> fptr = malloc(sizeof entry_file);
      args -> word = wordToSearch;

      if (pthread_create( & tid, NULL, readFrequenciesFromFile, args) == 0) {
        printf("Creating thread for file [%s] with ID %ld\n", in_file -> d_name, tid);
      } else {
        free(args);
      }

      fclose(entry_file);
    }
  }

  closedir(dir);
  return 0;
}

我会提到我在 VirtualBox 版本 6.1.10 r138449 (Qt5.6.2) 上使用 Ubuntu 18.04

我从哪里着手解决这个问题?这甚至是合理的还是我错过了什么?

【问题讨论】:

  • 请打印出buf的值。另外,请将命令行输出作为文本而不是图像发布。
  • @KenY-N 感谢您的输入,我已经更新了问题。

标签: c linux directory file-handling


【解决方案1】:

如果您始终检查函数调用的返回值以识别它们何时失败,您将更好地了解发生了什么问题。在这种情况下,如果您检查了 realpath() 调用的返回值,您可能已经被提示了。

我会假设你的主目录是/home/ra,正如你的代码所暗示的那样。注意您要打开的文件在/home/ra/Desktop/lab2/folder 中。您正在成功打开该目录并读取其条目,并且这些条目给出了其中文件的 基本名称 -- 即没有任何路径组件的名称。

无论您尝试通过打开文件还是通过计算它们的realpath()s 来解析这些文件名,都是相对于工作目录进行的。但是你启动程序的方式,它的工作目录是/home/ra/Desktop/lab2,而不是/home/ra/Desktop/lab2/folder,所以程序要求的文件确实存在。

您的选择包括

  • 从包含文件的文件夹中运行程序
  • 形成打开文件的正确路径——正确的绝对路径或相对于实际工作目录的正确路径。

【讨论】:

  • 我假设使用/home/ra是绝对路径..因为在路径中使用波浪号不起作用,程序输出Error! Unable to read directory
  • @RamiRaghfan 注意:~ 由您的 SHELL 扩展,而不是 C++,因此没有波浪号扩展。通常,您需要保留一个PATH_MAX 长度的数组,以使用一对strcpy()strcat() 或使用一个sprintf() 形成绝对路径
  • @RamiRaghfan, /home/ra一个绝对路径,但它不是您要打开的文件所在位置的路径。
【解决方案2】:

我看到ra@ra-VirtualBox:~/Desktop/lab2/folder$folderREADING FILE: /home/ra/Desktop/lab2/file3.txt 没有。问题是默认目录是~/Desktop/lab2/,这就是realpath()使用的;也许添加chdir() 会有所帮助:

chdir("/home/ra/Desktop/lab2/folder");
dir = opendir("/home/ra/Desktop/lab2/folder");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 2020-03-13
    • 2013-09-04
    相关资源
    最近更新 更多