使用Elixir和Hackney以流的形式读取数据
我正在使用,并且我正在尝试使用来自的指令将请求主体作为流来读取。 因为那里的代码是用Erlang编写的,所以我必须对其进行调整,使其在Elixir中工作:使用Elixir和Hackney以流的形式读取数据,elixir,Elixir,我正在使用,并且我正在尝试使用来自的指令将请求主体作为流来读取。 因为那里的代码是用Erlang编写的,所以我必须对其进行调整,使其在Elixir中工作: def read_body(max_length, client, acc) when max_length > byte_size(acc) do case :hackney.stream_body(client) do {:ok, data} -> read_body(max_length, clien
def read_body(max_length, client, acc) when max_length > byte_size(acc) do
case :hackney.stream_body(client) do
{:ok, data} -> read_body(max_length, client, acc <> data)
:done -> {:ok, acc}
{:error, reason} -> {:error, reason}
end
end
def read_body(max_length, client, acc) do
acc
end
问题是,我希望使用上面的代码只从正文中读取前20个字节的数据,但是acc
变量获取整个正文,当max\u length>byte\u size(acc)时,它或者不考虑保护,或者它只是在第一次调用:hackney.stream\u body/1
时读取所有正文
您认为如何解决此问题?您的read\u body/3
功能出现以下两种情况之一:
正如您所提到的,正在从:hackney.stream\u body/1
调用中立即返回整个正文,该调用恰好大于max\u length
,从而导致调用read\u body/3
的第二个定义
正文部分将作为read\u body/3
递归执行返回,直到acc
的大小不再小于max\u length
,这将导致调用read\u body/3
的第二个定义(与1的结果相同)
无论是:hackney.stream_body/1
函数还是read_body/3
保护程序实际上都不会基于最大长度限制返回正文的大小。在这两种情况下,acc
大于指定的max_length
,则:done
案例(或{:error,reason}
案例)将永远不匹配
为了限制返回正文的大小,一种解决方案是在case
表达式中添加两个额外的保护,并删除没有保护的read_body/3
的第二个定义:
def读取主体(最大长度、参考、附件)do
案例:hackney.stream_body(参考)do
{:好,当字节大小(acc)>最大长度->
读体(最大长度,参考,附件)
{:好的,数据}当(字节大小(数据)+字节大小(acc))>最大长度->
读取正文(最大长度,参考,acc字符串.slice(数据,0,最大长度-字节大小(acc)))
{:好的,数据}->
读取主体(最大长度、参考、acc数据)
:完成->
{:好的,acc}
{:错误,原因}->
{:错误,原因}
结束
结束
另一种解决方案可能是从max_length
中减去返回数据的大小,直到达到0
,然后忽略其余数据:
def read_body(0,ref,acc)do
案例:hackney.stream_body(参考)do
{:好的,{}->
读体(0,参考,附件)
:完成->
{:好的,acc}
{:错误,原因}->
{:错误,原因}
结束
结束
def读取体(最大长度,参考,附件)do
案例:hackney.stream_body(参考)do
{:好的,>}->
读取主体(0,参考,acc数据)
{:好的,数据}->
读取正文(最大长度-字节大小(数据),参考,acc数据)
:完成->
{:好的,acc}
{:错误,原因}->
{:错误,原因}
结束
结束
这两种解决方案具有相同的结果,但显示了解决同一问题的两种不同方法
acc = HackneyTutorial.read_body(20, client, "")
# I have my own methods for retrieving the client