简短的方法:
io_lib:format("~.8B", [Mode]).
... or:
io_lib:format("~.8B", [Mode band 8#777]).
For Mode = 33204
这两个将分别给你:["100664"]
and ["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/1
) for Mode = 33204
会给你这个结果:"rw-rw-r--"
.
如果有人不清楚,我将尝试解释我提供的片段背后的基本内容。
正如@macintux 已经提到的,33204
实际上是八进制数 100664 的十进制表示。这三个最低的八进制数字(664
) 可能有你需要的,所以我们通过按位和 (band
) 与三个八进制数字中的最高数字进行运算 (8#777
)。这就是为什么short way如此短——你只需告诉erlang进行转换Mode
字符串就像八进制数一样。
您提到的第二种表示形式(例如rw-rw-r--
, 一些东西ls
吐出)很容易从二进制表示中重现Mode
数字。请注意,三个八进制数字将为您提供正好九个二进制数字(8#644 = 2#110110100
)。事实上这是字符串rwxrwxrwx
其中每个元素替换为-
如果对应的数字等于0
。如果数字是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.
我希望你明白了。无论如何,如果您有疑问,请随时在评论中提出任何问题。