以下行应该测试当前文件是否是目录:
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
//file is a directory.
其中stbuf
的类型为
struct stat /* inode information returned by stat */
{
dev_t st_dev; /* device of inode */
ino_t st_ino; /* inode number */
short st_mode; /* mode bits */
short st_nlink; /* number of links to file */
short st_uid; /* owners user id */
short st_gid; /* owners group id */
dev_t st_rdev; /* for special files */
off_t st_size; /* file size in characters */
time_t st_atime; /* time last accessed */
time_t st_mtime; /* time last modified */
time_t st_ctime; /* time originally created */
};
且S_IFMT
和S_IFDIR
定义为
#define S_IFMT 0160000 /* type of file: */
#define S_IFDIR 0040000 /* directory */
我无法理解上面给出的陈述是如何起作用的?任何人都可以解释它背后的逻辑 感谢。
答案 0 :(得分:3)
它基本上表示如果你取出stbuf.st_mode
的所有位并将它们排列在上面
S_IFMT
中的位。您将生成第三行,即AND操作的结果。对于AND操作,请参阅以下truth table
,如果两个输入均为1
,则输出仅为1
。
input1| input2| output
------+-------+-------
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
对于每个相应的位位置,将0
置于数字下方,除非 指定位置中相应位的为{{1在这种情况下,您可以录制1
。
也许这个视觉形象会有所帮助:
1
将此结果位模式与st_mode | 0100 0000 0000 0000 0000 0000 0000 0000
S_IFMT | 1110 0000 0000 0000 0000 0000 0000 0000
bitwise & |===========================================
result | 0100 0000 0000 0000 0000 0000 0000 0000
的位模式进行比较。如果它们相等,你就有了一个目录。
也许这个问题Using Struct Stat()也会有所帮助。最后,除了此结构的所有血腥细节之外,stat(3) man page还有一些示例代码。
答案 1 :(得分:2)
按位AND获取与特定设置S_IFDIR
有关的位。
如果结果为S_IFDIR
,则设置该标志。 0160000
以八进制表示,表示整数的前3位。 0040000
是第二位,所以它们重叠。
答案 2 :(得分:2)
对于来自源和掩码的每对相应位,当且仅当两个位都设置为1时,逻辑AND操作给出一个on位(1)。这意味着掩码中未打开的所有位都归零。假设你有一个字节,其中的位为abcdefgh,其中每个字母都是一位,所以要么为0或1.如果你有一个掩码,其值为例如0或1。 00111000,AND这两个将导致00cde000。因此,使用掩码,您只能“切出”位的子串。通常,掩码只有一个位设置,在这种情况下,您将测试一个位。在您的示例中,掩码是S_IFMT。现在,您可以在掩码不受影响的3位空间中进行多个值编码,例如00101000,00011000或在掩码分隔的空间内具有所有1位的任何值(这是您的示例中的S_IFDIR) ),你可以比较。因此,如果简单的话,整个操作意味着“获取变量位的子串并检查它是否是预定义值之一”。这一切都是为了节省空间,如果不重要,设计师可能会为模式字段定义一个单独的变量。