這裡單純使用 write_file,其它 log 檔函數類似。
例如說在 /open/log/ 目錄下我們欲建立一個 eat_pill.log 檔,
它是基於玩家拿到 /d/obj/big_pill.c (屬性大補帖) 後,使用了
eat pill 指令去服用這顆藥丸的紀錄,那通常函數是這樣寫的:
int eat_pill(string str)
{
.
. 中略
.
write("你服下這顆藥丸後,感覺精力充沛,渾身充滿了幹勁!!\n");
write_file("/open/log/eat_pill.log",sprintf("%-12s : %s\n",
this_player()->query("name"),ctime(time()));
this_object()->remove();
return 1;
}
那它會產生什麼問題呢?就是後繼者看到這個檔案時
1. 它不曉得這個檔案是怎麼產生的
2. 它看到的時候可能檔案大小已高達數MB
針對第一點,可以改寫成底下程式段:
names=this_player()->query("name");
t=ctime(time());
str="";
if(!file_exists("/open/log/eat_pill.log"))
str="/d/obj/big_pill.c eat pill 專用 log 檔\n"+
"======================================================\n";
write_file("/open/log/eat_pill.log",sprintf("%s%-12s : %s\n",
str,names,t);
也就是說,如果這個檔案不存在,它在產生這個檔案的當下,
會在檔頭附加一段說明文字,讓後繼者可以知道,這個檔案的
產生,是從 /d/obj/big_pill.c 這裡來的。
針對第二點,有兩種做法,一種是使用 file_size 函數,即
if(file_size("/open/log/eat_pill.log") > 某值)
rm("/open/log/eat_pill.log");
然後再接上面針對第一點所寫的程式段即可,這時因為 rm 掉
了,它就會產生新的檔案並加上表頭,同時因為 rm 掉了產生
的新檔案,其 size 還很小,後面陸續添加內容時也不會短時
間 > 某值,就能繼續 log 下去。
還有一種做法是 rename
if(file_size("/open/log/eat_pill.log") > 某值)
{
rm("/open/log/eat_pill.old");
rename("/open/log/eat_pill.log","/open/log/eat_pill.old");
}
它會先去砍 .old 檔(如果有的話),再把 .log 檔 rename 成 .old 檔
通常當複數個地方需要使用到 log 檔時,將以上的處理包成一
個函數是比較好的做法,需要 log 時就呼叫同一函數來處理,
這樣對後繼者會是比較友善的做法。
最近因為在 sanc 又使用了 log 檔,順便規劃了日後欲採行的
做法,那其實 sanc 目前沒後繼者,說穿了就是對相當容易健忘
的我來說,是需要採行這種做法的。
(有幾個紀錄檔我就忘記程式段是寫在哪些物件上了)
Laechan