0

I want to encode a movie through IO.popen by ruby(1.9.3) in windows 7. If the file name contains only ascii strings, encoding proceed normally. But with unicode filename the script returns "No such file or directory" error. Like following code.

#-*- encoding: utf-8 -*-
command = "ffmpeg -i ü.rm"
IO.popen(command){|pipe|
  pipe.each{|line|
    p line
  }
}

I couldn't find whether the problem causes by ffmpeg or ruby. How can fix this problem?

4

1 回答 1

0

Windows 不使用 UTF-8 编码。Ruby 直接将 Unicode 文件名的字节序列发送到文件系统,当然文件系统不会识别 UTF-8 序列。似乎较新版本的 Ruby 已解决此问题。(我不确定。我正在使用 1.9.2p290,它仍然存在。)

您需要将 UTF-8 文件名转换为 Windows 使用的编码。

# coding: utf-8
code_page = "cp#{`chcp`.chomp[/\d+$/]}"   # detect code page automatically.
command = "ffmpeg -i ü.rm".encode(code_page)
IO.popen(command) do |pipe|
  pipe.each do |line|
    p line
  end
end

另一种方法是使用 Windows 使用的相同编码保存脚本。并且不要忘记更新编码声明。例如,我使用的是简体中文 Windows,它使用 GBK(CP936) 作为默认编码:

# coding: GBK
# save this file in GBK
command = "ffmpeg -i ü.rm"
IO.popen(command) do |pipe|
  pipe.each do |line|
    p line
  end
end

顺便说一句,按照惯例,建议使用do...end多行代码块而不是{...},除非在特殊情况下。

更新

底层文件系统 NTFS 使用 UTF-16 进行文件名编码。有效的文件名字符也是如此。但是,GBK 无法在您的日文 Windows 中进行编码,因此无法对 CP932 进行编码。因此,您无法将该特定文件名发送到您的cmd.exe,并且您不可能使用IO.popen. 对于 CP932 兼容的文件名,上面提供的编码方法可以正常工作。对于那些与 CP932 不兼容的文件名,最好将文件名修改为兼容的文件名。

于 2013-04-15T06:35:36.970 回答