Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
OrganizationAdvent CalendarQiitadon (β)
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

CSV.open で Encoding::UndefinedConversionError になる場合

More than 5 years have passed since last update.

Ruby 標準添付ライブラリの CSV で Windows-31J (Shift_JIS でも良いけど) な CSV を作っていたのだけれども、特定の文字が含まれていると Encoding::UndefinedConversionError になってしまう。

irb(main):011:0> CSV.open(File.join('/var/tmp/hoge.csv'), 'w', encoding: 'Windows-31J') do |csv|
irb(main):012:1*   csv << %w( d é f )
irb(main):013:1> end
Encoding::UndefinedConversionError: U+00E9 from UTF-8 to Windows-31J

最初は気楽に undef とか replace とか指定すれば良いんでしょ、とか思っていたんだけど。

irb(main):014:0> CSV.open(File.join('/var/tmp/hoge.csv'), 'w', encoding: 'Windows-31J', undef: :replace, replace: '*') do |csv|
irb(main):015:1*   csv << %w( d é f )
irb(main):016:1> end
ArgumentError: Unknown options:  undef, replace.

CSV.open に undef も replace も渡せない。
(話の流れで省略してるけど invalid も同じように渡せない)

実際に例外出しているのは CSV.new で、 CSV.new には決まったオプションしか渡せない。

書き出しの手間を考えると CSV ライブラリは使いたい、でも undef, replace 使いたい。
でも CSV.new には undef とか渡せない、でも文字コード変換して CSV 書き出したい。

実際に CSV.open が何をやっているかを参考にしつつ。
File.open して、それを CSV.new に渡すことにした。

irb(main):017:0> File.open(File.join('/var/tmp/hoge.csv'), 'w', encoding: 'Windows-31J', undef: :replace, replace: '*') do |file|
irb(main):018:1*   csv = CSV.new(file, encoding: 'Windows-31J')
irb(main):019:1>   begin
irb(main):020:2*     csv << %w( d é f )
irb(main):021:2>   ensure
irb(main):022:2*     csv.close
irb(main):023:2>   end
irb(main):024:1> end
=> <#CSV io_type:File io_path:"/var/tmp/hoge.csv" encoding:Windows-31J lineno:1 col_sep:"," row_sep:"\n" quote_char:"\"">


$ cat /var/tmp/hoge.csv

指定の通りに replace されてる。

Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away


No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
Help us understand the problem. What is going on with this article?