2

file:read_file_info/1状态“文件权限 [是] 总和”和“其他位......可能设置”的 Erlang 文档,没有灌输信心。而且,谷歌在这里不是我的朋友。

我希望在 Linux 机器上采用由 . 返回的模式file:read_file_info/133188并将其转换为更易于人类阅读和/或识别的东西,例如rw-r--r--or 644

非常感谢任何提示、链接或方向。

4

1 回答 1

4

捷径:

io_lib:format("~.8B", [Mode]).

... 或者:

io_lib:format("~.8B", [Mode band 8#777]).

对于Mode = 33204这两个将分别给你:["100664"]["664"]

漫长的道路:

print(Mode) ->
    print(Mode band 8#777, []).

print(0, Acc) when length(Acc) =:= 9 ->
    Acc;
print(N, Acc) ->
    Char = perm(N band 1, length(Acc) rem 3),
    print(N bsr 1, [Char | Acc]).

perm(0, _) ->
    $-;
perm(1, 0) ->
    $x;
perm(1, 1) ->
    $w;
perm(1, 2) ->
    $r.

这个(函数print/1Mode = 33204将为您提供以下结果:"rw-rw-r--".


如果有什么不清楚的地方,我会尝试在我提供的片段背后解释基本的东西。

正如@macintux 已经提到的那样33204,实际上是八进制数 100664 的十进制表示。这三个最低的八进制数字(三个八进制数字 ( )。这就是为什么 short way 这么短的原因——你只需告诉 erlang 转换为字符串,就好像它是八进制数一样。664band8#777Mode

您提到的第二种表示(例如rw-rw-r--ls吐出的东西)很容易从Mode数字的二进制表示中重现。请注意,三个八进制数字将给您正好九个二进制数字 ( 8#644 = 2#110110100)。实际上,这是rwxrwxrwx每个元素替换为-if 对应数字 equals的字符串0。如果 digit 是1元素保持不变。

所以有更清洁的方法来实现这一点:

print(Mode) ->
    print(Mode band 8#777, lists:reverse("rwxrwxrwx"), []).

print(0, [], Acc) ->
    Acc;
print(N, [Char0 | Rest], Acc) ->
    Char = char(N band 1, Char0),
    print(N bsr 1, Rest, [Char | Acc]).

char(0, _) ->
    $-;
char(1, C) ->
    C.

我希望你明白了。无论如何,如果您有疑问,请随时在评论中提出任何问题。

于 2012-11-01T21:26:08.473 回答