關於利用javascript獲取檔案大小

2009-06-08 8:57 am
最近在開發一個簡單的聊天室
原理是,利用javascript的settimeout重複檢查一個.txt檔案的大小
然後將其大小數字輸入一個hidden的input裹,每次檢查大小後,也比較input裹的大小數目,如果.txt檔案被更改,則會與input裹的數字(也就是前一次檢查時的大小數目)不一樣,這個時候就下載.txt的內容,然後顯示在<div id="show"></div>裹,如此類推

問題是,怎樣獲取.txt的檔案大小呢?
更新1:

原本這個聊天室是利用.txt存訊息,經由ajax不斷下載這個.txt獲得全部訊息,可想而之若果.txt裹的字數非常多時(可能高達幾mb),以ajax不斷下載的情況下,使用的帶寬將會以驚人的速度消耗;因此,我想利用不斷檢查檔案大小(訊息不能被修改,只能不斷地加上,所以檔案大小若果沒變的話,同樣內容亦不會變)檢測有否新留言加入,代替直接不斷地下載.txt檔案,以節省能源 若果javascript不能檢測檔案大小,還能有其他方法不斷地檢測大小以供利用ajax更新嗎?

更新2:

剛剛腦子一亮,想到以下方案代替檢測大小 先開啟一個新的.txt,定名為update.txt,內容只能是0-9,當有新留言時,除了將留言加入在儲存訊息之用的com.txt外,還更改update.txt裹的文字,將裹面的數字加上1;在檢測有否新留言時,先利用ajax獲取update.txt裹的數字,將它放在一個hidden的input裹,每隔5秒,再次取update.txt裹的數字,看看是否跟先前的那一次相同,若是,則代表有新留言,然後下載com.txt的內容並顯示,若否,則代表沒有新留言加入,如此類推;目的是利用一個字元代替下載com.txt的需要,以節省帶寬和伺服器的負荷 你認為行嗎?

更新3:

我知道區區一個聊天室系統,並不需要這麼笨拙的方法,這個系統其實是配合一個發貼系統,作者在編寫文章時,我希望其他人能夠觀看到他的文章進度,而且需要為文章作一個暫存,以供作者能隨時修改文章(因此不能利用MySQL),所以每發一個貼,就要為作者新增一個.txt檔案,並每隔一段時間將文章存入.txt裹,觀看者則利用ajax,不斷下載他的.txt,當然觀看者還能即時留言給他,整個就像一個聊天室,但現在問題在於能否有別的方法代替下載com.txt

更新4:

那麼,javascript能否實現檢查檔案的最後更新時間?

更新5:

對不起,最近在看有關sever push技術,非常有趣~~ [email protected]的回答非常精彩!

更新6:

最後還是利用php的死循環來不停檢測檔案size是否跟前一次更新時的一樣~

更新7:

最後一條問題~ 為什麼php的while死循環執行了一段時間後,會自動結束,有沒有解決方法,可以令死循環繼續無限地循環下去,直到循環正常地結束? 這是碼源: while($time == filesize($file)){ } echo ........檔案內容........; 其中$time是利用ajax傳送過來、有關上一次更新時該檔案的size的值, 利用while,如果上次更新時的size跟現在的file size一樣,則繼續循環直到file size跟上次的size不一樣,這樣,while便正常地結束,然後就是執行輸出檔案內容

更新8:

對,php回應後,ajax連接就會斷開,這是一次性的 所以當死循環傳來數據時,有2種可能性,1是check到size不同,2是超時 當兩者傳回是但一個時,可以利用ajax再次執行死循環,直到有下一次更新為止

更新9:

已經有初步的成果了

更新10:

<?php $time = $_POST['id']; $file = 'cache/art/'.$_POST['file'].'_a.txt'; while($time == filesize($file)){ clearstatcache(); } echo filesize($file); ? >

更新11:

當$file更新時,頁面立即收到最新size,是個好開始~ 而且測試了內存,佔用率非常低~!

更新12:

<?php $time = $_POST['id']; try{ do{ clearstatcache(); sleep(3); $file = filesize('cache/art/'.$_POST['file'].'_a.txt'); if($time != $file){ echo $file; } clearstatcache(); } while($time == $file); }catch(Exception $e){ } ? >

更新13:

以上代碼,雖然work,但有一個問題 當$time跟$file一樣時,就會無限循環,直到他們不一樣為此,然後就會輸出最新的$file數值 但是我發現這碼,對於在循環中時更新檔案,雖然while會正常地停止,但卻輸出不了$file的數值

回答 (2)

2009-06-12 4:26 pm
✔ 最佳答案
javascript 是可以實現檢查檔案的最後更新時間。

這工作須要 server side 程式的配合。

在用戶端用 ajax 技術,在背景模式下向 server side 端的程式索取目的檔的更新時間,用戶端不會察覺此動作。

傳回的時間是一串數字,下例是 "1244763440" ,是自01/01/1970 00:00:00 算過來的秒數。


待檢測的檔案: for_test.txt
abcde
12345

server side 程式: getmtime.cgi
#!/usr/bin/perl
my $mtime = (stat ("for_test.txt"))[9];
print "Content-type: text/html\n\n";
print $mtime;

client side 網頁: getmtime.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<script type='text/javascript'>

var req = null
var url = "/cgi-bin/getmtime.cgi"

if ( window.XMLHttpRequest )
{ req = new XMLHttpRequest()
req.overrideMimeType('text/xml')
}
else
{ var IEObj = new Array(
"MSXML2.XMLHTTP.6.0",
"MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP")

for (var i=0; i<IEObj.length && !req; i++ )
{ try { req = new ActiveXObject(IEObj[i]) }
catch (e){}
}
}

function getmtime()
{ req.abort()
req.onreadystatechange = expect_response
req.open('GET',url,true)
req.setRequestHeader('If-Modified-Since','0')
req.send(null)
}

function expect_response()
{ if ( req.readyState == 4 )
{ if ( req.status == 200 )
mtime = req.responseText
alert(mtime)
}
}

</script>

<body>

<a href="#" onclick="getmtime();return false">Get modification time of file</a>

</body>
</html>

請來測試:
http://w2.hkmalls.com/rc/getmtime.htm


2009-06-12 08:35:22 補充:
如要索取檔案 size ,將 getmtime.cgi 裡的 [9] 改為 [7] 就可。

2009-06-12 10:02:59 補充:
這裡給你多一個網頁選擇,或者你能較易理解。

這方法仍舊使用 server side 程式 getmtime.cgi 。
網頁方面不使用 ajax ,改用 iframe 呼叫 getmtime.cgi 。

2009-06-12 10:03:37 補充:
<html>

<script type='text/javascript'>

function connectserver()
{ document.getElementById("ifr").src = "http://w2.hkmalls.com/cgi-bin/getmtime.cgi"
}

function getmtime(arg)
{ mtime = arg
if ( !mtime ) { return }

alert(mtime)
}

2009-06-12 10:04:11 補充:
</script>

<body>

<a href="#" onclick="connectserver();return false">connect server</a>

2009-06-12 10:04:27 補充:
<iframe id="ifr" style="display:none;" onload="getmtime(this.contentWindow.document.body.innerHTML)"></iframe>

</body>
</html>

2009-06-12 10:05:00 補充:
請來測試
http://w2.hkmalls.com/rc/getmtime2.htm

2009-06-12 18:36:28 補充:
如果你不能用 cgi ,可以改用 php ,說明一下我就來補充。

2009-06-13 19:04:20 補充:
~~~~~~~~~~~~~~~~~~~~~~~~~

一定不要在 server side 執行不停的程式,人多使用 server 就會 down 機。
況且所有 server 都有設定程式最長執行時間,不會讓程式長時間執行。

上例有 link 讓你呼叫 ajax 程式,你可將此呼叫方式改為 serInterval 函數,每隔一段時間自動呼叫 ajax 程式。比如說每隔2分鐘:
<body onload="setInterval('getmtime()',120000)">

2009-06-13 19:21:08 補充:
順便講一下用 PHP 的方法,讓你多些選擇。

以下假設這三個檔案都放在同一目錄。:
for_test.txt
getmtime1b.php
getmtime1b.htm

2009-06-13 19:22:43 補充:
=======
getmtime1b.php
-------

<?php
$stat = stat('for_test.txt');
echo $stat['atime'];
?>

2009-06-13 19:27:00 補充:
========
getmtime1b.htm
--------
沿用上面的 getmtime.htm

在 body tag 加 onload 函數。
<body onload="setInterval('getmtime()',120000)">

這行 var url = "/cgi-bin/getmtime.cgi"
改為 var url = "getmtime1b.php"

========

2009-06-13 19:31:46 補充:
請來測試
http://w2.hkmalls.com/rc/getmtime1b.htm

這次使用 ajax 及 php 。
為方便測試,時間設為每2秒執行一次。

在意見欄那邊使用的 iframe 如使用 php 跟這邊大同小異,你小心看看就識得更改。

2009-06-13 19:44:34 補充:
更正:(php 檔)
echo $stat['atime']; 應為 echo $stat['mtime'];

atime 是最後讀取時間
mtime 是最後修改時間

2009-06-13 22:52:07 補充:
你是否對 ajax 有些誤解了?

網頁用 ajax 呼叫 php (或 cgi) 是一次性,php 一傳回數據就會結束,網頁方面每次送出請求亦只會等待一次回應。

所以網頁方面要利用 setInterval 每隔一段時間呼叫 php 一次。
2009-06-09 5:13 am
您應該用 PHP + MySQL+ AJAX 或類似技巧去做。JavaScript 不能處理伺服器端的資料的!
注意: txt 檔大小一樣不代表內容一定沒變!(要想想 txt 檔不斷加大的後果)
要考慮用 password login 您的系統的話,考慮以下的 AJAX framework 吧!
http://en.wikipedia.org/wiki/Quicknet


2009-06-10 00:00:56 補充:
我的意思是說,若有考慮過 txt 檔不斷加大是不好而用某種方式處理的話,就會發現 txt 檔大小一樣不代表內容一定沒變。
我不認為您的情況不能用 MySQL 呀!若您必要用 txt 檔以 ajax 方式傳至 client 的話,該 txt 檔也可以用 server 上的 script 產生呀!當然,選用 XML 來用 ajax 技巧是正路。

2009-06-10 00:01:52 補充:
若給我寫的話,我會選用時間來分辨內容有否更新: server 每次給 client 的資料中有最後更新時間,而 client 每次查詢 server 時可加入時間作為引數,server 可以以此判斷應否送出整套資料,還是只給最後更新時間, client 比對時間就能作正確的處理。

2009-06-10 20:05:13 補充:
發問者:
印象中 JavaScript 沒有檢查(server 上的)檔案的最後更新時間這種功能。另外,您真的在寫這種程式嗎?您有沒有想過 client 端如何使 txt 檔有變化呢?

2009-06-12 22:27:20 補充:
回答者 002 說 javascript 是可以實現檢查檔案的最後更新時間,但提供的方法根本就是用 server 上的 script (.cgi 檔,以 Perl 寫成) 產生“檔案的時間”,並於 client 以 ajax 方式取得。筆者認為如要那樣作,不如用筆者以上的建議,設計 server 上的 script ( Perl 、 PHP 、 ASP等),因應 client 送上的引數(如時間、 checksum 等),判斷要回傳(或不回傳)什麼資料好了。


收錄日期: 2021-04-25 00:03:34
原文連結 [永久失效]:
https://hk.answers.yahoo.com/question/index?qid=20090608000051KK00095

檢視 Wayback Machine 備份