将文件写入 S3 时的字符编码问题
Character encoding issue when writing a file to S3
当我尝试在 S3 上创建一个包含 ‘’ “” – — é
等特殊字符的文件时,文件中写入了不正确的数据,并且文件中出现了奇怪的字符。我用的是亚马逊官方提供的aws-sdk
ruby gem 。下面是示例代码:
@bucket = AppConfig.s3_bucket
@s3 = AWS::S3.new
file = @s3.buckets[@bucket].objects['amit/test']
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read)
我也试过:
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/html')
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/plain')
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/plain', :content_encoding => 'utf-8')
输出文件如下所示:
‘test1’ “test2†test–test—test3 é-test
我已经尝试使用 aws-sdk 版本 1.11.1
和 1.65.0
。
看来您只需要指定文件的字符编码即可。如果您将其视为 Windows-1252 编码而不是 UTF-8,您看到的字符串 ‘test1’ “test2†test–test—test3 é-test
就是您的测试字符串的样子。如果您在浏览器中查看(如果没有设置编码,通常默认为 1252),请尝试将浏览器使用的编码更改为 UTF-8(菜单类似于 View → Encoding
)。
我不熟悉 AWS api,但看一看 the docs 建议您可以使用 write
的 :content_type
选项指定内容类型称呼。尝试:
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => "text/plain; charset=utf-8")
(或者您可能需要 text/html
而不是 text/plain
。)
如果我理解文档,这应该会导致 AWS 在检索 object.
时设置 content-type header
这完全取决于您使用什么来获取 object 读取 header。如果不是,您可能必须配置您的客户端以告诉它数据是 UTF-8。
可能您的文件名之一是 unicode,而您没有设置适当的语言环境来处理它。
检查:
$ locale
LANG=
LC_CTYPE="C"
LC_COLLATE="C"
LC_TIME="C"
LC_NUMERIC="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=
修复:
$ locale -a |grep en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_US.UTF-8
$ export LC_ALL=en_US.UTF-8
注意:根据您的 shell,您需要使用适当的方法来设置环境变量,export LC_ALL=en_US.UTF-8
或 setenv LC_ALL en_US.UTF-8
或其他。
盗自:http://randysofia.com/2014/06/06/aws-cli-and-your-locale/
当我尝试在 S3 上创建一个包含 ‘’ “” – — é
等特殊字符的文件时,文件中写入了不正确的数据,并且文件中出现了奇怪的字符。我用的是亚马逊官方提供的aws-sdk
ruby gem 。下面是示例代码:
@bucket = AppConfig.s3_bucket
@s3 = AWS::S3.new
file = @s3.buckets[@bucket].objects['amit/test']
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read)
我也试过:
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/html')
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/plain')
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => 'text/plain', :content_encoding => 'utf-8')
输出文件如下所示:
‘test1’ “test2†test–test—test3 é-test
我已经尝试使用 aws-sdk 版本 1.11.1
和 1.65.0
。
看来您只需要指定文件的字符编码即可。如果您将其视为 Windows-1252 编码而不是 UTF-8,您看到的字符串 ‘test1’ “test2†test–test—test3 é-test
就是您的测试字符串的样子。如果您在浏览器中查看(如果没有设置编码,通常默认为 1252),请尝试将浏览器使用的编码更改为 UTF-8(菜单类似于 View → Encoding
)。
我不熟悉 AWS api,但看一看 the docs 建议您可以使用 write
的 :content_type
选项指定内容类型称呼。尝试:
file.write("‘test1’ “test2” test–test—test3 é-test", :acl => :public_read, :content_type => "text/plain; charset=utf-8")
(或者您可能需要 text/html
而不是 text/plain
。)
如果我理解文档,这应该会导致 AWS 在检索 object.
时设置 content-type header这完全取决于您使用什么来获取 object 读取 header。如果不是,您可能必须配置您的客户端以告诉它数据是 UTF-8。
可能您的文件名之一是 unicode,而您没有设置适当的语言环境来处理它。
检查:
$ locale
LANG=
LC_CTYPE="C"
LC_COLLATE="C"
LC_TIME="C"
LC_NUMERIC="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=
修复:
$ locale -a |grep en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_US.UTF-8
$ export LC_ALL=en_US.UTF-8
注意:根据您的 shell,您需要使用适当的方法来设置环境变量,export LC_ALL=en_US.UTF-8
或 setenv LC_ALL en_US.UTF-8
或其他。
盗自:http://randysofia.com/2014/06/06/aws-cli-and-your-locale/