You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以二进制写入UTF-8字符串?解决epub双重编码报错问题

解决双重UTF-8编码文件修复时的“wide character in subroutine”错误

你遇到的这个错误,核心原因是Perl严格区分字节字符串和字符字符串:当你尝试写入包含宽字符的字符字符串时,若未明确指定二进制模式,Perl会触发该错误。结合你的场景,问题出在文件读写模式和编码处理的顺序上,以下是具体解决方案:

正确处理代码

use Mojo::Base -strict;
use Mojo::File;
use Encode qw(decode_utf8 encode_utf8);

# 二进制模式读取原始文件,获取未被自动解码的双重编码字节流
my $raw_bytes = Mojo::File->new('part0000.html')->slurp({mode => '<:raw'});

# 对字节流做一次UTF-8解码,得到正常的字符(解决双重编码问题)
my $correct_chars = decode_utf8($raw_bytes);

# 将字符重新编码为UTF-8字节流
my $fixed_bytes = encode_utf8($correct_chars);

# 二进制模式写入文件,避免Perl自动编码导致的宽字符错误
Mojo::File->new('fixed.html')->spurt($fixed_bytes, {mode => '>:raw'});

错误原因分析

  1. 未指定二进制读写模式:默认的slurp()和spurt()会用文本模式处理,Perl会自动尝试将字节解码为字符,这会破坏你需要处理的双重编码字节流,后续的解码/编码操作就会混乱。
  2. 错误的编码操作顺序:之前的代码中,若slurp()已经自动解码了字节流,再调用decode_utf8相当于对字符做二次解码,生成的字符串会包含无效的宽字符,写入时自然触发错误。
  3. utf8::downgrade的局限性:这个函数只能将纯ASCII的字符字符串转为字节字符串,一旦存在中文、日文等宽字符,直接调用会失败,无法解决根本问题。

内容的提问来源于stack exchange,提问作者shirha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:47:27