写入数据不保留编码

13

我有一个类似于以下字符串的字符串:

str <- "ていただけるなら"
Encoding(str) #returns "UTF-8"

我将它写入磁盘:

write.table(str, file="chartest", quote=F, col.names=F, row.names=F)

现在我在Notepad++中查看该文件,它被设置为UTF-8无BOM编码,我得到了如下内容:

<U+3066><U+3044><U+305F><U+3060><U+3051><U+308B><U+306A><U+3089>

这个过程出了什么问题?我希望文本文件中显示的字符串与R中的字符串一致。

这是在Windows 7上,R版本为2.15。


尝试这个:writeLines(str, "chartest2.txt", useBytes=TRUE) - Montgomery Clift
2个回答

16

这是Windows下R语言的一个令人烦恼的“特性”。到目前为止,我找到的唯一解决方案是临时地通过编程将您的区域设置切换到所需的语言环境以解码相关文本。因此,在上述情况下,您需要使用日语环境。

## This won't work on Windows
str <- "ていただけるなら"
Encoding(str) #returns "UTF-8"
write.table(str, file="c:/chartest.txt", quote=F, col.names=F, row.names=F)
## The following should work on Windows - first grab and save your existing locale
print(Sys.getlocale(category = "LC_CTYPE"))
original_ctype <- Sys.getlocale(category = "LC_CTYPE")
## Switch to the appropriate local for the script
Sys.setlocale("LC_CTYPE","japanese")
## Now you can write your text out and have it look as you would expect
write.table(str, "c:/chartest2.txt", quote = FALSE, col.names = FALSE, 
            row.names = FALSE, sep = "\t", fileEncoding = "UTF-8")
## ...and don't forget to switch back
Sys.setlocale("LC_CTYPE", original_ctype)

上述操作会生成两个文件,如下截图所示。第一个文件显示的是Unicode代码点,而不是您想要的内容,而第二个文件则显示了通常所期望的字形。 日文文本 目前还没有人能够解释为什么R会出现这种情况。这不是Windows的不可避免特性,因为正如我在这篇帖子中提到的那样,Perl以某种方式绕过了此问题。

感谢您的回复。日语只是一个例子,我希望能找到适用于所有语言类型的解决方案。不过听起来并不太乐观。 - qua
@qua - 是的,我认为这可能是一个随机的例子,因为你在一个相当奇怪的地方断开了日语字符串。不幸的是,目前我认为R没有更好的解决方案,但如果你找到了一个,请创建自己的答案来回答这个问题!我同意,如果你事先不知道脚本,你可能会在我的方法上遇到困难,因为(除了其他问题之外),它需要你猜测所使用的脚本,并且根本没有确定编码类型的绝对方法。 - SlowLearner
@SlowLearner 有没有办法列出所有有效的 LC_CTYPE 值? - statsNoob
我不知道。我有一个非常具体的使用目的,所以当我找到我想要的东西时就停止了搜索。 - SlowLearner
@SlowLearner 你太棒了!! - Mohamed Kamal

2
你尝试过使用参数fileEncoding吗?
write.table(str, file="chartest", quote=F, col.names=F, row.names=F, fileEncoding="UTF-8")

1
谢谢您的建议。不过尝试了那个似乎不起作用。 - qua
好的,所以当时我在我的工作电脑上尝试过(在Mac OSX上),它可以工作,但自那以后我在家里的电脑上尝试过(Windows 7),它确实无法工作。 - plannapus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接