Вопросы | c

Как вы получаете список каталогов в C?

Вопрос

andrewrk | 110286 просмотров | рейтинг: 0

Как вы сканируете каталог для папок и файлов в C? Это должно быть кроссплатформенным.



Ответы

PW.

+ 5 -
opendir / readdir - это POSIX. Если POSIX недостаточно для переносимости, которую вы хотите достичь, проверьте Apache Portable Runtime  


Will Dean

+ 71 -
Следующая программа POSIX напечатает имена файлов в текущем каталоге:
 #define _XOPEN_SOURCE 700
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main (void)
{
  DIR *dp;
  struct dirent *ep;
  dp = opendir ("./");

  if (dp != NULL)
  {
    while (ep = readdir (dp))
      puts (ep->d_name);

    (void) closedir (dp);
  }
  else
    perror ("Couldn't open the directory");

  return 0;
}
 

Предоставлено: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html. Проверено в Ubuntu 16.04.  


Andrew Grant

+ 18 -
Строгий ответ: нельзя, так как сама концепция папки не является кроссплатформенной. На платформах MS вы можете использовать _findfirst, _findnext и _findclose для вида 'c', а FindFirstFile и FindNextFile для базовых вызовов Win32. Вот ответ C-FAQ: http://c-faq.com/osdep/readdir.html  


Pascal

+ 9 -
Не существует стандартного способа C (или C ++) для перечисления файлов в каталоге. В Windows вы можете использовать функции FindFirstFile / FindNextFile для перечисления всех записей в каталоге. В Linux / OSX используйте функции opendir / readdir / closedir.  


Clayton

+ 2 -
Список каталогов сильно различается в зависимости от рассматриваемой ОС / платформы. Это потому, что различные операционные системы используют свои собственные внутренние системные вызовы для достижения этой цели. Решением этой проблемы будет поиск библиотеки, которая маскирует эту проблему и является переносимой. К сожалению, не существует решения, которое работает на всех платформах без нареканий. В POSIX-совместимых системах вы можете использовать библиотеку для достижения этой цели, используя код, опубликованный Clayton (на который изначально ссылается книга У. Ричарда Стивенса «Расширенное программирование в UNIX»). Это решение будет работать в системах * NIX, а также в Windows, если у вас установлен Cygwin. В качестве альтернативы, вы можете написать код для обнаружения базовой ОС, а затем вызвать соответствующую функцию листинга каталогов, которая будет содержать «правильный» способ перечисления структуры каталогов под этой ОС.  


Isak Savo

+ 7 -
GLib - это библиотека переносимости / утилит для C, которая лежит в основе графического инструментария GTK +. Может использоваться как отдельная библиотека. Он содержит переносимые обертки для управления каталогами. Подробности смотрите в документации по Glib File Utilities. Лично я бы даже не подумал написать большое количество C-кода без чего-то похожего на GLib. Переносимость - это одно, но также приятно получить структуры данных, помощники потоков, события, основные циклы и т. Д. Бесплатно Джайкс, я почти начинаю походить на продавца :) (не волнуйтесь, glib с открытым исходным кодом (LGPL), и я никак не связан с ним)  


Mehrdad

+ 1 -
Наиболее похожий метод на readdir, вероятно, использует малоизвестное семейство функций _find.  


David Wu

+ 14 -
Я создал C-заголовок с открытым исходным кодом, который решает эту проблему. В настоящее время он поддерживает POSIX и Windows. Пожалуйста, проверьте это: https://github.com/cxong/tinydir
 tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");

while (dir.has_next)
{
    tinydir_file file;
    tinydir_readfile(&dir, &file);

    printf("%s", file.name);
    if (file.is_dir)
    {
        printf("/");
    }
    printf("/n");

    tinydir_next(&dir);
}

tinydir_close(&dir);
 




PW.

+ 5 -
Вы можете найти образец кода по ссылке викибукса
 /**************************************************************
 * A simpler and shorter implementation of ls(1)
 * ls(1) is very similar to the DIR command on DOS and Windows.
 **************************************************************/
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path)
{
  struct dirent *entry;
  DIR *dp;

  dp = opendir(path);
  if (dp == NULL)
  {
    perror("opendir");
    return -1;
  }

  while((entry = readdir(dp)))
    puts(entry->d_name);

  closedir(dp);
  return 0;
}

int main(int argc, char **argv) {
  int counter = 1;

  if (argc == 1)
    listdir(".");

  while (++counter <= argc) {
    printf("/nListing %s.../n", argv[counter-1]);
    listdir(argv[counter-1]);
  }

  return 0;
}
 

 


Will Dean

+ 71 -
Уже поздно, но я не могу удержаться ... Используя систему C int system(char*), вы можете выполнять любые действия через переносимый C-интерфейс. Вам нужно будет загрузить приложение с языком, специфичным для системы (например, Shell / Bash, DOS, PowerShell), но по крайней мере вам не нужно будет связывать дополнительные библиотеки. И, в отличие от dirent, вы можете делать все, что не зависит от платформы, используя его. Пример перечисления каталогов с Linux (в основном псевдо):
 system("ls . > some_file_or_pipe_or_whatever") //
fscanf(file_or_pipe_or_whatever, "%s", a_line_from_ls);
 




Теги

c | file | folder | common-tasks