2014-05-21 34 views
0

我寫了一個偵聽udp端口的小腳本,並將所有傳入消息(一個JSON對象)存儲在單個文件中。空文件包含JSON格式的數組。 我正在尋找一種有效的方法來將來自多個客戶端的所有(同時)傳入消息存儲在此單個文件中。 文件大小可以是幾百兆字節大。根據需要解析文件並追加新對象效率不高。追加JSON對象而不解析它的有效方法

你有辦法嗎?

編輯 我的解決方案的基礎上,@ TJ-克羅德方法:

var dgram = require("dgram"); 
var fs = require("fs"); 
var udp_server = dgram.createSocket("udp4"); 

var udp_server_port = 5000 

udp_server.on("message", function (msg, rinfo) { 

     var json_part = "{\"message\": " + msg + "}"; 

     fs.open('./data/stats.json','r+',function(err,fd){ 
      if(err) throw err 

      fs.fstat(fd,function(err,stats){ 
       if(err) throw err    

       if(stats.size>2){ 
        json_part = new Buffer(','+json_part+']','utf-8'); 
        var pos = parseInt(stats.size)-1; 
       }else{ 
        json_part = new Buffer('['+json_part+']','utf-8'); 
        var pos = 0; 
       } 

       fs.write(fd,json_part, 0, json_part.length, pos, function(err,written,buffer){ 
        if(err) throw err 
        fs.close(fd,function(){ 
        }); 
       }); 

      }); 

     }); 

}); 

udp_server.bind(udp_server_port); 

問候,馬庫斯

回答

3

從根本上說,你需要:

  1. 打開文件使用可搜索,可寫入的流。

  2. 尋求到它的結尾。

  3. 備份一個字符(超過數組的結尾])。

  4. 寫出一個逗號(如果這不是第一項)和新條目的JSON。

  5. 撰寫結束日期]

  6. 關閉文件。

望着文檔的NodeJS,它看起來像步驟2-4(可以說5)完成一起,使用fs.writeposition說法。 (請確保您使用r+打開文件,而不是「追加」模式之一。)

+0

看起來簡單而好:謝謝! Nodejs負責併發寫訪問單個文件(這是阻止)本身或我必須管理這種情況? – arbyter

+0

@arbyter:NodeJS *不能*確保對文件的原子訪問(因爲其他進程可以嘗試寫入),並且據我所知,默認情況下不會嘗試。我沒有用Node API完成它,但通常你可以讓文件系統拒絕對文件進行寫訪問(甚至讀訪問),同時用適當的標誌打開文件。您可能必須研究如何使用Node的API來做到這一點(我沒有立即看到我在'fs.open'文檔中想到的選項。) –

+2

@arbyter:我的建議是使用數據庫而不是文件系統上的平面文件。然後,您可以在有數據庫時向數據庫插入消息。 MongoDb適用於存儲json對象。通過這種方式,您可以搜索,排序,獲取消息範圍等。 – Ben