我一直在使用Perl构建模拟器,我面临的一个问题是解析位于计算机中的JSON文件。当我尝试从我的服务器中取出它们时,它们工作正常......
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
return \%arrInfo;
}
我们假设@arrURLS
是:
my @arrURLS = ("file:///C:/Users/Test/Desktop/JSONS/first.json", "file:///C:/Users/Test/Desktop/JSONS/second.json");
上面的网址是那些不起作用的网址,但如果我将其更改为:
my @arrURLS = ("http://127.0.0.1/test/json/first.json", "http://127.0.0.1/test/json/second.json");
它有效。
此外,我想使用比Mojo::UserAgent
更好的内容,因为它似乎有点慢,当我使用Coro
与LWP::Simple
时,速度要快得多,但不幸的是Coro
Perl 5.22 ......
答案 0 :(得分:4)
用户代理主要用于通过http下载文件。通常不期望它们处理文件系统URI。您需要自己open
和read the file,或使用File::Slurp之类的模块为您做到这一点。
它可能看起来像这样。
use File::Slurp 'read_file';
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
if (substr($strURL, 0, 4) eq 'file') {
$arrInfo{basename($strURL, '.json')} = read_file($strURL);
} else {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
}
return \%arrInfo;
}
答案 1 :(得分:2)
我自己使用WWW::Mechanize执行所有此类任务。来自doc:
WWW :: Mechanize是LWP :: UserAgent的合适子类,您也可以 使用任何LWP :: UserAgent的方法。
这意味着您也可以使用file://
类型的网址提供。
例如,以下单行转储您的passwd
文件。
perl -MWWW::Mechanize -E 'say WWW::Mechanize->new->get("file://etc/passwd")->content'
或没有任何错误处理的示例...
use 5.014;
use warnings;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('file://some/path');
say $mech->content;
无论如何,可能最好用于本地文件一些file-based
实用程序,我自己使用Path::Tiny模块的所有文件,它具有(不仅限于)文件slurping的方法,例如:
use Path::Tiny;
my $content = path('/some/path')->slurp;
或只是简单的perl:
open my $fh, '<', '/some/file' or die "...";
my $content = do { local $/; <$fh> };
close $fh;
答案 2 :(得分:1)
总是要说明您正在使用的其他模块,这一点非常重要。我认为您的代码使用Method::Signatures
,并且我已经测试了下面的代码,只是检查它是否与该模块一起编译
Mojolicious 是一个出色的工具,但它专注于HTTP URL。 LWP::UserAgent
更通用,documentation for LWP
说明了这个
提供HTTP样式通信的面向对象模型。在此框架内,我们目前支持访问http,https,gopher,ftp,新闻,文件和mailto资源
你的方法就像这样。它没有经过测试
method get_content(\@urls) {
my %info;
my $ua = LWP::UserAgent->new;
for my $url (@urls) {
my $res = $ua->get($url);
die $res->status_line unless $res->is_success;
my $name = basename($url) . '.json';
my $data = $res->decoded_content;
$info{$name} = $data;
}
\%info;
}
我还鼓励你在Perl代码的上下文中删除匈牙利表示法,因为该语言已经有了表示数据类型的符号
@arrURLS
重复显示此arrURLS
是数组的信息,而%arrInfo
错误,因为此arrInfo
是哈希。 $arrData
实际上是标量,虽然可能有一些指示它也是引用可能会有所帮助,$arrURLS[0]
也是标量(因此是美元)
使用$arrURLS
(这是一个与@arrURLS
完全不同的变量)也无法阻止您使用