unicode - raku 可以避免这个 Malformed UTF-8 错误吗?
问题描述
当我运行这个 raku 脚本时......
my $proc = run( 'tree', '--du', :out);
$proc.out.slurp(:close).say;
我在 MacOS 上收到此错误...
Malformed UTF-8 near bytes ef b9 5c
...而不是像zsh这样的树输出,这是我想要的...
.
├── 00158825_20210222_0844.csv
├── 1970-Article\ Text-1971-1-2-20210118.docx
├── 1976-Article\ Text-1985-1-2-20210127.docx
├── 2042-Article\ Text-2074-1-10-20210208.pdf
├── 2045-Article\ Text-2076-1-10-20210208.pdf
├── 6.\ Guarantor\ Form\ (A).pdf
我试过slurp(:close, enc=>'utf8-c8')
了,错误是一样的。
我也试过...
shell( "tree --du >> .temp.txt" );
my @lines = open(".temp.txt").lines;
dd @lines;
...并且错误是相同的。
打开 .temp.txt 揭示了这一点......
.
â<94><9c>â<94><80>â<94><80> [ 1016739] True
â<94><9c>â<94><80>â<94><80> [ 9459042241] dir-name
â<94><82>Â Â â<94><9c>â<94><80>â<94><80> [ 188142] Business
â<94><82>Â Â â<94><82>Â Â â<94><9c>â<94><80>â<94><80> [ 9117] KeyDates.xlsx
â<94><82>Â Â â<94><82>Â Â â<94><9c>â<94><80>â<94><80> [ 13807] MondayNotes.docx
文件-我给了这个...
.temp.txt: text/plain; charset=unknown-8bit
有什么建议吗?
[这是 Catalina 10.15.17,终端编码 Unicode(UTF-8) 欢迎使用™ v2020.10。实现™ 编程语言 v6.d。基于 MoarVM 版本 2020.10 构建。]
解决方案
您的代码页/语言环境似乎不是 Utf8。(或者tree
忽略代码页并使用不同的东西。)
快速……得到一些东西,从中得到任何东西;是使用8位单字节编码。
run( 'tree', '--du', :out, :enc<latin1> );
通常,查看 Utf8 的解码开始出错的地方就足够了。
也就是说,让我们看看您的预期输出和文件输出。
say '├──'.encode; # utf8:0x<E2 94 9C E2 94 80 E2 94 80>
在您的文件中,您有
â<94><9c>â<94><80>â<94><80> [ 1016739] True
等等……</p>
say 'â'.encode('latin1'); # Blob[uint8]:0x<E2>
<E2><94><9c><E2><94><80><E2><94><80>
<E2 94 9c E2 94 80 E2 94 80>
utf8:0x<E2 94 9C E2 94 80 E2 94 80>
是的,它们看起来非常相似。
因为它们完全相同。
所以它似乎在某种程度上产生了预期的输出。
这似乎证实了,是的tree
,您的代码之间存在编码问题。这表明代码页/语言环境设置错误。
您还没有真正提供足够的信息来确定到底哪里出了问题。您应该使用run
二进制模式来为我们提供准确的输出。
say run('echo', 'hello', :out, :bin).out.slurp;
# Buf[uint8]:0x<68 65 6C 6C 6F 0A>
您也没有说<9c>
文件中的字面意思是否为四个文本字符,或者它是否是您用来打开文件将二进制数据转换为文本的任何功能。
如果所有示例数据都是相同的,那也很好。
在一个稍微相关的注释上……</p>
由于tree
给出了文件名,并且文件名不是 Unicode,因此在这里使用utf8-c8
是合适的。
(通常同样适用于用户名和密码。)
这是我在计算机上运行的一些代码,希望能说明原因。
say dir(:test(/^ r.+sum.+ $/)).map: *.relative.encode('utf8-c8').decode
# (résumé résumé résumé résumé)
dir(:test(/^ r.+sum.+ $/)).map: *.relative.encode('utf8-c8').say
# Blob[uint8]:0x<72 65 CC 81 73 75 6D 65 CC 81>
# Blob[uint8]:0x<72 C3 A9 73 75 6D 65 CC 81>
# Blob[uint8]:0x<72 C3 A9 73 75 6D C3 A9>
# Blob[uint8]:0x<72 65 CC 81 73 75 6D C3 A9>
say 'é'.NFC;
# NFC:0x<00e9>
say 'é'.NFD
# NFD:0x<0065 0301>
sub to-Utf8 ( Uni:D $_ ){
.map: *.chr.encode
}
say to-Utf8 'é'.NFC
# (utf8:0x<C3 A9>)
say to-Utf8 'é'.NFD
# (utf8:0x<65> utf8:0x<CC 81>)
所以é
要么被编码为一个组合代码点,要么被编码为<C3 A9>
两个分解代码点<65> <CC 81>
。
我真的为此目的创建了 4 个“同名”文件吗?
是的。是的,我做到了。
推荐阅读
- pycharm - 龟函数在pycharm中不起作用
- java - Azure Java SDK - 同时使用映像创建多个 VM
- tensorflow - 给定一个 Tensoflow MetaGraph,我怎样才能找到这个图的输入张量和输出张量?
- r - R 数小时内无法处理繁重的任务
- xml - 使用 SoapUI 发出请求时面临的问题
- cassandra - 可以直接将 ScyllaDB 2.1.x 升级到 ScyllaDB 3.xx 吗?
- spring-boot - 如何通过弹性搜索找到排序后的数据——spring boot
- python - 错误:引发 portNotOpenError serial.serialutil.SerialException:尝试使用未打开的端口
- symfony - 所有 URL 都转到 web/index.html
- android - 使用底部工作表对话框时,应用程序 MapFragment 锁定为模式