我遇到了一个奇怪的问题。我有一个程序从外部源接收以字节为单位的数据,作为回报,我执行一些业务逻辑并发送回复。我们遇到了一个关于 String.to_charlist 的奇怪问题。
在 iex 中试试这个:
String.to_charlist <<169, 99, 111, 114, 94, 51, 94, 51, 94, 66, 52, 57, 49, 49, 49, 32, 32, 49, 48, 51, 53, 94, 67, 79, 77, 80, 76, 69, 84, 69, 68, 94, 49, 49, 52, 50, 52, 53, 94, 75>>
这将引发以下错误:
** (UnicodeConversionError) invalid encoding starting at <<169, 99, 111, 114, 94, 51, 94, 51, 94, 66, 52, 57, 49, 49, 49, 32, 32, 49, 48, 51, 53, 94, 67, 79, 77, 80, 76, 69, 84, 69, 68, 94, 49, 49, 52, 50, 52, 53, 94, 75>>
(elixir) lib/string.ex:2035: String.to_charlist/1
现在,如果您去掉第一个字节并依次尝试:
String.to_charlist <<99, 111, 114, 94, 51, 94, 51, 94, 66, 52, 57, 49, 49, 49, 32, 32, 49, 48, 51, 53, 94, 67, 79, 77, 80, 76, 69, 84, 69, 68, 94, 49, 49, 52, 50, 52, 53, 94, 75>>
你得到:
'cor^3^3^B49111 1035^COMPLETED^114245^K'
有没有不同的方式我应该将这些字节转换为字符串?我知道一些像 169 这样的字符可能无法显示,但是推荐的处理方式是什么?
谢谢你的帮助。
我确实找到了这个:
<<169 :: utf8, 0>>
返回 <<194, 169, 0>> 其中添加了 194。因此,如果将其粘贴到 iex 中,输出似乎是正确的。
<<194, 169, 99, 111, 114, 94, 51, 94, 51, 94, 66, 52, 57, 49, 49, 49, 32, 32, 49, 48, 51, 53, 94, 67, 79, 77, 80, 76, 69, 84, 69, 68, 94, 49, 49, 52, 50, 52, 53, 94, 75>>
我是否需要编写一个函数来遍历字节并调用 <> 然后减少返回的字节(0 concat 除外)?
String.to_charlist/1
首先是多余的:
String.to_charlist <<99, 111, 114, 94, 51, 94, 51, 94>>
之所以有效,只是因为utf8
和latin1
在 interval 中共享相同的代码点1–127
。以下内容足以获得完全有效的二进制文件:
<<99, 111, 114, 94, 51, 94, 51, 94>>
#⇒ "cor^3^3^"
不幸的是,您收到的不是utf8
编码,Elixir 没有内置工具来在编码之间转换二进制文件。您不能只删除有意义的符号。
我建议使用codepagex
package 进行该转换:
Codepagex.from_string(<<99, 111, 114, 94, 51, 94, 51, 94>>, :iso_8859_1)
#⇒ "cor^3^3^"
另一种方法是使用 erlang 的unicode.characters_to_binary/2
:
:unicode.characters_to_binary(
<<169, 99, 111, 114, 94, 51, 94, 51, 94>>, :latin1, :utf8
)
#⇒ "©cor^3^3^"
使用Kernel.SpecialForms.for/1
理解的另一种解决方案:
to_string(for <<c :: 8 <- <<169, 99, 111, 114, 94, 51, 94, 51, 94>> >>, do: c)
#⇒ "©cor^3^3^"
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句