Erlang:奇怪的输出格式
Erlang: strange output formatting
Windows 7 x64,Erlang-OTP 17。
我写了这样的简单模块:
-module (somequery).
-export ([fbquery/2]).
fbquery(P1,P2) ->
inets:start(),
ssl:start(),
token = "78a8shd67tyajsndweiu03hr83h19j",
Encoded = {"Authorization","Basic " ++ base64:encode_to_string(lists:append([token,":",""]))},
ContentType = "application/xml",
Headers = [Encoded, {"Content-Type",ContentType}],
Options = [{body_format,binary}],
{ok, File}=file:read_file(P1),
Res = httpc:request(post, {"https://datapi.com/api/xml4-8", Headers, ContentType, File}, [], Options),
file:write_file(P2, io_lib:fwrite("~p.\n", [Res])).
它在交互和编译中都有效,Res term 显示数据
59> Res.
{ok,{{"HTTP/1.1",200,"OK"},
[{"connection","keep-alive"},
{"date","Tue, 05 May 2015 10:58:53 GMT"},
{"server","nginx"},
{"vary","Accept-Encoding"},
{"content-length","5508"},
{"content-type","application/xml; charset=utf-8"},
{"x-frame-options","SAMEORIGIN"},
{"p3p",
"CP=\"To see our privacy policy, go here: http://www.datapi.com/policies/privacy\""},
{"strict-transport-security","max-age=31536000"}],
<<"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<response xmlns=\"http://www.datapi.com/api/\" status=\""...>>}}
但在输出文件(P2 参数)中我看到了这个
{ok,{{"HTTP/1.1",200,"OK"},
[{"connection","keep-alive"},
{"date","Tue, 05 May 2015 10:58:53 GMT"},
{"server","nginx"},
{"vary","Accept-Encoding"},
{"content-length","5508"},
{"content-type","application/xml; charset=utf-8"},
{"x-frame-options","SAMEORIGIN"},
{"p3p",
"CP=\"To see our privacy policy, go here: http://www.datapi.com/policies/privacy\""},
{"strict-transport-security","max-age=31536000"}],
<<60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,
101,110,99,111,100,105,110,103,61,34,117,116,102,45,56,34,63,62,10,60,
114,101,115,112,111,110,115,101,32,120,109,108,110,115,61,34,104,116,
116,112,58,47 ... MORE NUMBERS HERE ....101,62,10>>}}.
真奇怪,我记得在完全交互模式下我没有遇到过这样的问题。有什么建议吗?
UPD:这很有趣,但只有当接收到 XML 包含非 ASCII(非拉丁语?)字符时才会出现问题。在其他情况下,文件中的所有 XML 都是正确的。
那是因为运行时不确定您的终端是否可以显示非 ASCII unicode。所有字符串都只是整数列表,所有二进制文件都只是分成 8 位字节的长字符串。因此,您看到的数字 是 您想要查看的数据,只是它的原始形式。
要以您想要的方式显示它,请尝试使用像 io:format/2
这样的显示函数,并使用 ~tp
替换而不是 ~p
替换。在你的情况下,写入文件,你可能需要做:
write(Filename, UTF8_data) ->
file:write_file(Filename, unicode:characters_to_binary(UTF8_data, utf8)).
read(Filename) ->
case file:read_file(Filename) of
{ok, Data} -> {ok, unicode:characters_to_list(Data, utf8)};
Other -> Other
end.
请参阅文档中的 Using Unicode in Erlang。它比以前好多了,但仍然有点烦人(所以用一些函数包装它,比如上面的 read/1 和 write/2)。
就是说... Windows 在涉及 unicode(和一般编码)时有其独特的愚蠢形式,我的大部分 Erlang 经验都是在 Linux 和 BSD 上——我在 Windows 上做的唯一事情是 Wx 中的客户端 GUI。
Windows 7 x64,Erlang-OTP 17。 我写了这样的简单模块:
-module (somequery).
-export ([fbquery/2]).
fbquery(P1,P2) ->
inets:start(),
ssl:start(),
token = "78a8shd67tyajsndweiu03hr83h19j",
Encoded = {"Authorization","Basic " ++ base64:encode_to_string(lists:append([token,":",""]))},
ContentType = "application/xml",
Headers = [Encoded, {"Content-Type",ContentType}],
Options = [{body_format,binary}],
{ok, File}=file:read_file(P1),
Res = httpc:request(post, {"https://datapi.com/api/xml4-8", Headers, ContentType, File}, [], Options),
file:write_file(P2, io_lib:fwrite("~p.\n", [Res])).
它在交互和编译中都有效,Res term 显示数据
59> Res.
{ok,{{"HTTP/1.1",200,"OK"},
[{"connection","keep-alive"},
{"date","Tue, 05 May 2015 10:58:53 GMT"},
{"server","nginx"},
{"vary","Accept-Encoding"},
{"content-length","5508"},
{"content-type","application/xml; charset=utf-8"},
{"x-frame-options","SAMEORIGIN"},
{"p3p",
"CP=\"To see our privacy policy, go here: http://www.datapi.com/policies/privacy\""},
{"strict-transport-security","max-age=31536000"}],
<<"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<response xmlns=\"http://www.datapi.com/api/\" status=\""...>>}}
但在输出文件(P2 参数)中我看到了这个
{ok,{{"HTTP/1.1",200,"OK"},
[{"connection","keep-alive"},
{"date","Tue, 05 May 2015 10:58:53 GMT"},
{"server","nginx"},
{"vary","Accept-Encoding"},
{"content-length","5508"},
{"content-type","application/xml; charset=utf-8"},
{"x-frame-options","SAMEORIGIN"},
{"p3p",
"CP=\"To see our privacy policy, go here: http://www.datapi.com/policies/privacy\""},
{"strict-transport-security","max-age=31536000"}],
<<60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,
101,110,99,111,100,105,110,103,61,34,117,116,102,45,56,34,63,62,10,60,
114,101,115,112,111,110,115,101,32,120,109,108,110,115,61,34,104,116,
116,112,58,47 ... MORE NUMBERS HERE ....101,62,10>>}}.
真奇怪,我记得在完全交互模式下我没有遇到过这样的问题。有什么建议吗?
UPD:这很有趣,但只有当接收到 XML 包含非 ASCII(非拉丁语?)字符时才会出现问题。在其他情况下,文件中的所有 XML 都是正确的。
那是因为运行时不确定您的终端是否可以显示非 ASCII unicode。所有字符串都只是整数列表,所有二进制文件都只是分成 8 位字节的长字符串。因此,您看到的数字 是 您想要查看的数据,只是它的原始形式。
要以您想要的方式显示它,请尝试使用像 io:format/2
这样的显示函数,并使用 ~tp
替换而不是 ~p
替换。在你的情况下,写入文件,你可能需要做:
write(Filename, UTF8_data) ->
file:write_file(Filename, unicode:characters_to_binary(UTF8_data, utf8)).
read(Filename) ->
case file:read_file(Filename) of
{ok, Data} -> {ok, unicode:characters_to_list(Data, utf8)};
Other -> Other
end.
请参阅文档中的 Using Unicode in Erlang。它比以前好多了,但仍然有点烦人(所以用一些函数包装它,比如上面的 read/1 和 write/2)。
就是说... Windows 在涉及 unicode(和一般编码)时有其独特的愚蠢形式,我的大部分 Erlang 经验都是在 Linux 和 BSD 上——我在 Windows 上做的唯一事情是 Wx 中的客户端 GUI。