【问题标题】:convert JSON buffer to string in perl在perl中将JSON缓冲区转换为字符串
【发布时间】:2021-01-04 22:02:19
【问题描述】:

问题:尝试使用 Perl 脚本将 json 缓冲区数据写入文件。

场景:

我将在 Postgres 中保存二进制数据。

所以为了重新创建场景,我将“geeks”转换为二进制格式并存储在 Postgres 中。

Input :  geeks
Output : 1100111 1100101 1100101 1101011 1110011  

Nodejs 从 postgres 查询二进制数据并以 json 格式发送如下响应。

[
 {
   "lo_get": {
     "type": "Buffer",
     "data": [
       49,
       49,
       48,
       48,
       49,
       49,
       49,
       32,
       49,
       49,
       48,
       48,
       49,
       48,
       49,
       32,
       49,
       49,
       48,
       48,
       49,
       48,
       49,
       32,
       49,
       49,
       48,
       49,
       48,
       49,
       49,
       32,
       49,
       49,
       49,
       48,
       48,
       49,
       49
     ]
   }
 }
]

以下是我编写的 Perl 脚本,但我不确定如何将原始字符串(即“geeks”)写入文件..

    $req = HTTP::Request->new(GET => $url);
    $res = $ua->request($req);
    $response = decode_json($res->content);
    if ($res->is_success & @$response) {
        $string = @$response[0]->{Output}->{data};
        print ($string);   
    } 

    open my $fh, ">", "data_out.json";
    print $fh encode_json($string);
    close $fh;

我不确定如何获取以“极客”为内容的文件。

【问题讨论】:

    标签: node.js json perl


    【解决方案1】:
    my $binary =
       pack 'C*',
          @{ $response->[0]{lo_get}{data} };
    
    say $binary;   # '1100111 1100101 1100101 1101011 1110011
    
    my $bytes =
       pack 'C*',
          map { oct("0b$_") }
             split(' ', $binary);
    
    say $bytes;    # geeks
    

    转成二进制

    这毫无意义。除了在访问数据库时将字节转换为二进制表示或返回的不必要的额外工作之外,它将所需的存储空间乘以 9!

    【讨论】:

    • 谢谢。我将在 Postgres 中有二进制格式的数据。我创建了上面的示例以适应我的场景。
    • 但是您没有将其存储为“二进制格式”(这意味着一种高效但可能不是人类可读的格式);您正在获取“二进制数据”(仅表示任意字节)并存储它的 text (即人类可读)表示。这与您声称的相反!
    • 没错。它的二进制数据。在这种情况下我需要考虑其他事情吗?
    • 再一次,它不是二进制数据;它是文本数据。您应该存储二进制数据,而不是它的文本表示。您将二进制(数字的文本表示)与二进制数据(一个非常松散的术语,意思是“人类不可读,因为它使用所有字节值”)混淆了。
    • 只需删除字符串到其二进制表示的转换。在 Perl 方面,您只需使用 my $bytes = pack 'C*', @{ $response->[0]{lo_get}{data} };
    【解决方案2】:

    解决问题的算法:

    • 将数据获取到哈希引用中
    • 使用运算符 mapsplit 将数字转换为 bin 表示形式
    • 将使用chroct bin 编号转换的数组加入字符串
    • 根据需要处理字符串
    use strict;
    use warnings;
    use feature 'say';
    
    use JSON;
    use Data::Dumper;
    
    my $fname   = 'data.txt';
    my $input   = do { local $/; <DATA> };
    my $data    = from_json($input);
    
    say 'Read: ' . Dumper($data);
    
    my $str = join '', map { chr } @{$data->[0]{lo_get}{data}};
    my @bin =  map { '0b' . $_ } split ' ', $str;
    
    $str = join '', map { chr oct($_) } @bin;
    
    say  'Out: ' . $str;
    
    open my $fh, '>', $fname
        or die "Couldn't open $fname";
    
    say $fh $str;
    
    close $fh;
    
    __DATA__
    [
     {
       "lo_get": {
         "type": "Buffer",
         "data": [
           49,
           49,
           48,
           48,
           49,
           49,
           49,
           32,
           49,
           49,
           48,
           48,
           49,
           48,
           49,
           32,
           49,
           49,
           48,
           48,
           49,
           48,
           49,
           32,
           49,
           49,
           48,
           49,
           48,
           49,
           49,
           32,
           49,
           49,
           49,
           48,
           48,
           49,
           49
         ]
       }
     }
    ]
    

    script.pl运行

    Read: $VAR1 = [
              {
                'lo_get' => {
                              'type' => 'Buffer',
                              'data' => [
                                          49,
                                          49,
                                          48,
                                          48,
                                          49,
                                          49,
                                          49,
                                          32,
                                          49,
                                          49,
                                          48,
                                          48,
                                          49,
                                          48,
                                          49,
                                          32,
                                          49,
                                          49,
                                          48,
                                          48,
                                          49,
                                          48,
                                          49,
                                          32,
                                          49,
                                          49,
                                          48,
                                          49,
                                          48,
                                          49,
                                          49,
                                          32,
                                          49,
                                          49,
                                          49,
                                          48,
                                          48,
                                          49,
                                          49
                                        ]
                            }
              }
            ];
    
    Out: geeks
    

    文件内容data.txt

    geeks
    

    【讨论】:

    • @ikegami -- 好吧 OP 已经改变了他的问题几次,最初他有文本,然后他改变了 array 以包含二进制数据的 ASCII 表示,我不得不改变我的代码采用此更改。好吧,我无法预测二进制数据的内容是什么,为了安全起见,我认为它可能是用 UTF-8 编码的——嗯,在输出上删除 :encoding(utf8) 不是问题。
    • 8 个 10 字符组,一旦解码,字符在 0 到 255 之间。使用 UTF-8 编码的可能性极小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 2019-07-30
    • 2019-07-29
    相关资源
    最近更新 更多