2012-06-20 42 views
8

MongoDB手冊:的Perl和MongoDB的二進制數據

By default, all database strings are UTF8. To save images, binaries, and other non-UTF8 data, you can pass the string as a reference to the database.

我獲取網頁,並想要保存以便以後處理的內容。

  • 我不能依賴於元字符集,因爲很多網頁有utf8的內容,但錯誤地宣稱ISO-8859-1或類似
  • 所以不能用Encode(不知道原始字符集)
  • 因此,我想保存以便以後處理

片段我的代碼的內容簡單地as flow of bytes(二進制數據):

sub save { 
    my ($self, $ok, $url, $fetchtime, $request) = @_; 

    my $rawhead = $request->headers_as_string; 
    my $rawbody = $request->content; 

    $self->db->content->insert(
     { "url" => $url, "rhead" => \$rawhead, "rbody" => \$rawbody }) #using references here 
     if $ok; 

    $self->db->links->update(
     { "url" => $url }, 
     { 
      '$set' => { 
       'status'  => $request->code, 
       'valid'  => $ok, 
       'last_checked' => time(), 
       'fetchtime' => $fetchtime, 
      } 
     } 
    ); 
} 

,但得到的錯誤:

Wide character in subroutine entry at /opt/local/lib/perl5/site_perl/5.14.2/darwin-multi-2level/MongoDB/Collection.pm line 296.

這是我存儲數據的地方。

問題:在MondoDB中存儲二進制數據的唯一方法是對它們進行編碼,例如用base64?

+0

如果您將'$ rawhead'和'$ rawbody'設置爲手冊中給出的示例(即「\ xFF \ xFE \ xFF」'),它會給出相同的警告嗎? – raina77ow

回答

4

它看起來像另一個悲傷的故事_utf8_標誌...

我可能是錯的,但似乎該消息的HTTP :: headers_as_stringcontent方法返回的字符串作爲字符序列。但MongoDB驅動程序期望顯式傳遞給它的字符串作爲「二進制文件」成爲八位字節序列 - 因此是警告劇。

一個比較難看的解決辦法是採取倒在$ rawhead的utf8標誌和$原始信體在你的代碼(我不知道是不是應該真的MongoDB的驅動程序本身做了什麼?),通過這樣的事情...

_utf8_off $rawhead; 
_utf8_off $rawbody; # ugh 

另一種方法是使用encode('utf8', $rawhead) - 但在從數據庫中提取值時應該使用decode,我懷疑它不是更醜。

0

你的數據是字符,不是八位字節。你的假設似乎是,你只是將事情通過八位字節傳遞,但是你必須通過解碼傳入的文本數據以某種方式違反了這種假設,甚至可能沒有你注意到。

所以,不要解碼,數據保留字節,存儲到數據庫不會失敗。