【问题标题】:Perl & MongoDB binary dataPerl & MongoDB 二进制数据
【发布时间】:2012-06-22 08:50:59
【问题描述】:

来自MongoDB 手册:

默认情况下,所有数据库字符串都是 UTF8。要保存图像、二进制文件、 和其他非 UTF8 数据,您可以将字符串作为对 数据库。

我正在获取页面并希望存储内容以供以后处理。

  • 我不能依赖元字符集,因为很多页面都有 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,
            }
        }
    );
}

但得到错误:

子程序入口中的宽字符 /opt/local/lib/perl5/site_perl/5.14.2/darwin-multi-2level/MongoDB/Collection.pm 第 296 行。

这是我存储数据的唯一地方。

问题:在 MondoDB 中存储二进制数据的唯一方法是对它们进行编码,例如使用 base64?

【问题讨论】:

  • 如果您将$rawhead$rawbody 设置为手册中给出的示例(即"\xFF\xFE\xFF"),它会给出相同的警告吗?

标签: perl mongodb


【解决方案1】:

看起来又是一个关于_utf8_flag的悲伤故事……

我可能错了,但似乎 HTTP::Message 的 headers_as_stringcontent 方法将它们的字符串作为字符序列返回。但是 MongoDB 驱动程序希望作为“二进制文件”显式传递给它的字符串是八位字节序列 - 因此是警告戏剧。

一个相当丑陋的解决方法是在你的代码中删除 $rawhead 和 $rawbody 上的 utf8 标志(我想知道它不应该由 MongoDB 驱动程序本身完成吗?),通过类似这样的东西......

_utf8_off $rawhead; 
_utf8_off $rawbody; # ugh

另一种方法是使用encode('utf8', $rawhead) - 但是在从数据库中提取值时你应该使用decode,我怀疑它并不丑。

【讨论】:

    【解决方案2】:

    您的数据是字符,而不是八位字节。您的假设似乎是您只是将事物作为八位字节传递,但您必须在早些时候通过解码传入的文本数据以某种方式违反了该假设,甚至可能在您没有注意到的情况下。

    所以根本不解码,数据保持八位字节,存储到数据库中不会失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      • 2011-07-12
      • 1970-01-01
      • 2014-11-06
      相关资源
      最近更新 更多