首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >utf-16le到UTF-8

utf-16le到UTF-8
EN

Stack Overflow用户
提问于 2020-07-19 20:56:29
回答 3查看 63关注 0票数 0

我在osx terminal上使用php打开用windows生成的文件。

我确认文件是utf-16le编码的

$file --mime myfile.ini

myfile.ini: text/plain; charset=utf-16le

现在,我使用此脚本将其转换为UTF-8。

代码语言:javascript
复制
while ($line = fgets($handle)) {
    $line = rtrim($line);
    $line = mb_convert_encoding($line,"UTF-8","UTF-16LE"); 
    var_dump($line);
}

不知何故,它显示了像这样的腐败

string(63) "䘀爀漀洀䐀愀琀攀㴀㈀ ㄀㄀⸀ ㄀⸀ ㄀ഀ਀"

如何获得正确的编码?

When I don use mb_convert_encoding

代码语言:javascript
复制
while ($line = fgets($handle)) {
    $line = rtrim($line);
    $line = mb_convert_encoding($line,"UTF-8","UTF-16LE"); 
    var_dump($line);
    if (preg_match('/Optimization/',$line)){print "hit";}
}

var_dump显示奇怪的结果,为什么是28?

代码语言:javascript
复制
string(28) "Optimization=0"

preg_match也没有命中。

EN

回答 3

Stack Overflow用户

发布于 2020-07-19 21:25:07

如果流不是以ASCII码兼容的编码方式编码的,那么fgets()不可能可靠地检测到行结束。类似地,当rtrim()寻找例如\n ('LINE FEED (LF)' (U+000A))时,它需要一个文字0x0A,但在UTF-16LE中,编码是0x0A00。糟糕的事情可能会发生。

我建议你以4字节的倍数来读取文件,这样你就不会拆分单个字符,并在成功重新编码文件之前忘记行尾:

代码语言:javascript
复制
$output = '';
while ($line = fgets($handle, 4 * 4096)) {
    $output .= mb_convert_encoding($line, "UTF-8", "UTF-16LE"); 
}
var_dump(bin2hex($output));

理想情况下,将输出保存到文件中,以便可以使用文本编辑器或十六进制编辑器检查结果。

票数 0
EN

Stack Overflow用户

发布于 2020-07-19 21:31:35

您可以尝试这样做:

代码语言:javascript
复制
while ($line = fgets($handle)) {
    $line = rtrim($line);
    $line = iconv(mb_detect_encoding($line, mb_detect_order(), true), "UTF-8", $line);; 
    var_dump($line);
}
票数 0
EN

Stack Overflow用户

发布于 2020-07-19 21:32:34

最后,我使用UTF-16BE而不是UTF-16LE,它显示了正确的字符串。

我的问题解决了。

代码语言:javascript
复制
 $line = mb_convert_encoding($line,"UTF-8","UTF-16BE"); 

但是我不知道它为什么会起作用,

甚至连file都说This file is utf-16le推荐

代码语言:javascript
复制
$file --mime myfile.ini

myfile.ini: text/plain; charset=utf-16le
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62980581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档