使用stat(2) - 获取Inode编号和硬链接计数

时间:2011-12-13 01:49:24

标签: c

我在获取此信息时遇到问题。我不知道如何访问它。我目前的代码片段如下所示。随意批评那里已经存在的问题。感谢。

DIR *directory;
struct dirent *fileEntry; 

directory = opendir(argv[1]);
if(directory != NULL)
 {
  while((fileEntry = readdir(directory)) != NULL)
   {
    int i = 0;
    char *filename[];
    filename[i] = fileEntry -> d_name; // Get filename
    // Get inode here
    // Get hard link count here
    i++; 
   }
  }

3 个答案:

答案 0 :(得分:6)

您是否已查看该联机帮助页? http://linux.die.net/man/2/stat您应该可以通过以下方式访问它们:

fileEntry->st_ino; /* inode number */
fileEntry->st_nlink;  /* number of hard links */

答案 1 :(得分:1)

你在这里有一些非惯用语法:

int i = 0;
char *filename[];
filename[i] = fileEntry -> d_name; // Get filename

更容易:

char *filename = fileEntry->d_name;

当然,如果您只是打印一次文件名而不再使用它,则不需要变量。

struct dirent看起来像这样:

       struct dirent {
           ino_t          d_ino;       /* inode number */
           off_t          d_off;       /* offset to the next dirent */
           unsigned short d_reclen;    /* length of this record */
           unsigned char  d_type;      /* type of file; not supported
                                          by all file system types */
           char           d_name[256]; /* filename */
       };

因此,要获得inode编号,您将执行类似的操作:

int inum = fileEntry->d_ino;

同样,如果您不打算再次使用该变量,则不需要变量。

如果您认为变量名称可以提高程序的易读性,那么请将它们留在其中。

while((fileEntry = readdir(directory)) != NULL) {
    printf("inode %d is for file %s\n",
        fileEntry->d_ino, fileEntry->d_name);
}

i++只是为您的程序制作错误。由于int i=0位于块的顶部,因此变量i会在每次循环迭代时重新初始化为0,这很好,因为您的char *filename[]变量不会不要分配任何存储来包含多个指针。 (它只是声明filename是一个字符指针数组 - 它不会为数组留出任何存储空间。)

<强>更新

随着我对正在发生的事情的新认识,我得到了一些建议:

如果要创建单个大型数组来容纳包含数据的大型字符串,则可以执行此操作。使用malloc(3)为数组分配内存是明智的,这样如果需要更多存储空间,就可以realloc(3)循环内的数组。

看起来像这样:

char *s = malloc(100);
s[0] = '\0';
int size = 100;
int pos = 0;
while (file = readdir(dir)) {
    int filenamelen = strlen(file->d_name);

    if (pos + filenamelen > size) {
        int newsize = size + 300; /* 256 + inode + links */
        if (newsize < size) {
            /* integer wraparound, big mistake */
        }
        s = realloc(s, newsize);
        size = newsize;
    }

    /* &s[pos] sillyness is to avoid re-scanning
       the array for the NUL on every filename */
    strcat(&s[pos], file->d_name);

    pos += filenamelen+1; /* leave NUL in string */

    struct stat sb;

    stat(file->d_name, &sb);

    int stats_len;

    /* terminate inode and link count with NUL */
    stats_len = sprintf(s[pos], "%ld %ld\0", (long) file->d_ino, (long) sb.st_nlink);

    pos += stats_len;
}

fwrite(s, pos, 1, SOCKET_FILP);

如果您想以递增方式向客户端发送数据,那么您不需要一个数组来保存数据,您可以立即开始发送数据,而不是等到您解析了{ {1}}所有文件的信息。

看起来像这样:

stat(2)

NUL字节可以让您的客户端有机会正确解析文件名。它们不能包含NUL字节,但它们可以包含所有其他字节值,因此这提供了无歧义的解析。

增量方法更容易,因为没有真正的内存管理可以处理。标准IO接口处理所有这些。 (我不是100%确信我的大字符串版本是正确的.C字符串处理是微妙的。)

答案 2 :(得分:0)

要直接获取目录中的硬链接计数,请执行以下操作:

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
unsigned int getNumberOfHardLinks(char* pathToTheDirectory){
        struct stat* stForHardLinksCount = (struct stat*)malloc(sizeof(struct stat));
        stat(fpath, stForHardLinksCount);
        nlink_t numberOfHardLinks = stForHardLinksCount->st_nlink;
        printf("\n%u\n",numberOfHardLinks);
        return numberOfHardLinks  ;
}

对于inode编号,您可以这样做:

fileEntry->d_ino;

代码。